Định dạng JSON trong Bash — jq
Sử dụng Định dạng và Làm đẹp JSON miễn phí trực tiếp trên trình duyệt — không cần cài đặt.
Dùng thử Định dạng và Làm đẹp JSON trực tuyến →Khi một script triển khai bắt đầu xử lý phản hồi API hoặc xác thực file cấu hình trong CI, việc biết cách định dạng JSON trong bash nhanh chóng trở nên thiết yếu. Hai công cụ bao gồm 99% các trường hợp thực tế là jq và python3 -m json.tool — cả hai đều có thể chạy pipeline định dạng json bash một cách đáng tin cậy, xác thực với mã thoát và tích hợp gọn gàng vào quy trình CI/CD. Để kiểm tra một lần không cần terminal, Trình định dạng JSON dựa trên trình duyệt xử lý ngay lập tức. Hướng dẫn này bao gồm cài đặt jq, định dạng pipe và file, hàm xác thực, tích hợp CI/CD trong GitHub Actions, pre-commit hooks, mẫu heredoc và khi nào nên dùng fallback Python stdlib.
- •
jq .định dạng VÀ xác thực đồng thời — thoát với mã 1 khi JSON không hợp lệ - • Dùng
jq -etrong pipeline CI: thoát khác không khi đầu ra rỗng/false/null - •
jq . file.json > /dev/null && echo "valid"— xác thực mà không thay đổi đầu ra - •
python3 -m json.toolhoạt động trên bất kỳ hệ thống nào mà không cần cài đặt thêm - • Không bao giờ làm
jq . f.json > f.json— shell cắt bớt file nguồn trước khi jq đọc nó
Định Dạng JSON trong Bash là Gì?
Định dạng JSON trong bash có nghĩa là chuyển đổi JSON gọn gàng, thu nhỏ thành đầu ra được thụt lề, dễ đọc cho người. Dữ liệu cơ bản không thay đổi — chỉ khác nhau về khoảng trắng và ngắt dòng. Trong các ngữ cảnh scripting, điều này quan trọng vì hai lý do: khả năng đọc khi debug và xác thực khi trình định dạng kiểm tra lại cú pháp như một tác dụng phụ. Các công cụ như jq phân tích JSON đầy đủ trước khi định dạng lại, có nghĩa là một lần chạy định dạng thành công cũng là một kiểm tra tính hợp lệ ngầm. Hành vi kép đó — định dạng và xác thực trong một bước — là điều làm cho jq hữu ích trong các pipeline tự động.
{"service":"payments-api","version":"2.4.1","database":{"host":"db-prod-01.internal","port":5432,"pool_size":20},"cache":{"enabled":true,"ttl":300}}{
"service": "payments-api",
"version": "2.4.1",
"database": {
"host": "db-prod-01.internal",
"port": 5432,
"pool_size": 20
},
"cache": {
"enabled": true,
"ttl": 300
}
}jq — Định Dạng JSON trong Bash
jq là tiêu chuẩn thực tế cho xử lý JSON trong script shell (jq 1.6+, bash 4+). Đây là bộ xử lý JSON dòng lệnh được xây dựng có mục đích có thể định dạng, lọc, chuyển đổi và xác thực JSON. Bộ lọc nhận diện . truyền đầu vào không thay đổi, nhưng được định dạng. Khi jq không thể phân tích đầu vào, nó thoát với mã 1 — đây là điều làm cho nó lý tưởng cho scripting: định dạng và xác thực là một hoạt động duy nhất.
Cài đặt jq
# macOS brew install jq # Debian / Ubuntu apt-get install -y jq # Fedora / RHEL / CentOS dnf install jq # Alpine (image Docker) apk add --no-cache jq # Xác minh jq --version # jq-1.7.1
Định dạng từ stdin và từ file
# Chuyển JSON nội tuyến qua jq
echo '{"host":"db-prod-01.internal","port":5432}' | jq .
# Định dạng file trực tiếp (in ra stdout)
jq . config/feature-flags.json
# Định dạng với thụt lề 4 khoảng trắng
jq --indent 4 . config/feature-flags.json
# Định dạng dùng tab thay vì khoảng trắng
jq --tab . config/feature-flags.jsonGhi đầu ra đã định dạng vào file
# Lưu đầu ra đã định dạng (KHÔNG chuyển hướng lại cùng file) jq . compact.json > formatted.json # Gọn gàng (thu nhỏ) — ngược lại của định dạng jq -c . formatted.json
jq thoát với mã 1 khi JSON không hợp lệ, mã 0 khi thành công và mã 5 khi có lỗi sử dụng. Dùng điều này trong các câu lệnh if và bộ bảo vệ || exit 1 trong toàn bộ script của bạn.Sắp xếp khóa và loại bỏ màu
# Sắp xếp tất cả khóa theo thứ tự bảng chữ cái (hữu ích cho diff xác định) jq --sort-keys . config/app-config.json # Tắt đầu ra màu khi ghi vào file log jq --monochrome-output . response.json >> deploy.log
Tài Liệu Tham Khảo Tùy Chọn jq
Các cờ jq được sử dụng phổ biến nhất cho quy trình định dạng và xác thực:
Xác Thực JSON trong Script Bash
Xác thực và định dạng là cùng một hoạt động trong jq — nó phân tích trước khi in. Chuyển hướng stdout đến /dev/null khi bạn chỉ muốn mã thoát mà không có đầu ra đã định dạng. Mẫu bên dưới có thể tái sử dụng trong các script triển khai, pre-commit hooks và pipeline CI. Trong ứng phó sự cố, điều đầu tiên tôi làm với payload API không quen thuộc là chuyển qua jq — nó biến một bức tường JSON thu nhỏ thành thứ gì đó tôi thực sự có thể đọc và debug.
Hàm xác thực có thể tái sử dụng
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ JSON hợp lệ: $file"
return 0
else
echo "✗ JSON không hợp lệ: $file" >&2
return 1
fi
}Hủy bỏ triển khai khi cấu hình không hợp lệ
CONFIG="infra/k8s/app-config.json"
validate_json "$CONFIG" || { echo "Hủy bỏ triển khai: cấu hình không hợp lệ" >&2; exit 1; }Xác thực tất cả file JSON trong một thư mục
find ./config -name "*.json" | while read -r f; do jq . "$f" > /dev/null 2>&1 || echo "KHÔNG HỢP LỆ: $f" done
-e / --exit-status đi xa hơn: nó cũng thoát với mã 1 khi đầu ra là false hoặc null. Dùng để khẳng định rằng một trường cụ thể là truthy: jq -e '.feature_flags.new_checkout' config.json.Định Dạng JSON từ File và Phản Hồi API
Hai nguồn JSON phổ biến trong script shell là các file trên đĩa và phản hồi HTTP API qua curl. Mỗi cái có một mẫu xử lý hơi khác. Đối với file, mối quan tâm chính là chỉnh sửa an toàn tại chỗ. Đối với phản hồi API, chi tiết quan trọng là ngăn thanh tiến trình của curl để nó không làm hỏng đầu vào của jq.
Định dạng tại chỗ an toàn cho một file
# Định dạng và ghi đè an toàn bằng file tạm tmp=$(mktemp) jq --indent 2 . config/feature-flags.json > "$tmp" && mv "$tmp" config/feature-flags.json echo "Đã định dạng config/feature-flags.json"
Định dạng phản hồi curl API
# Định dạng trạng thái triển khai từ API DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Định dạng và lọc đồng thời
# Lấy đã định dạng + lọc chỉ lỗi từ endpoint giám sát
curl -s "https://monitoring.internal/api/events?level=error&limit=10" \
| jq '[.events[] | {id, message, timestamp, service}]' \
|| { echo "Không thể lấy hoặc phân tích events" >&2; exit 1; }Mẫu || { ... } rất quan trọng ở đây. Nếu không có nó, một curl thất bại hoặc phản hồi API bị lỗi sẽ âm thầm đi qua và bước tiếp theo trong script của bạn sẽ hoạt động trên dữ liệu trống hoặc một phần. Nếu bạn cần kiểm tra các phản hồi lồng nhau phức tạp mà không cần viết biểu thức lọc trước, Trình định dạng JSON dựa trên trình duyệt cho phép bạn dán phản hồi thô và điều hướng cây tương tác.
Định Dạng JSON trong Pipeline CI/CD
CI là nơi các cổng xác thực JSON quan trọng nhất — một cấu hình bị lỗi đến môi trường production gây đau đớn hơn nhiều để rollback so với lỗi pipeline. Hầu hết các đối thủ tài liệu jq cho việc sử dụng terminal một lần; các mẫu bên dưới là những gì tôi sử dụng trong quy trình SRE production để bắt lỗi cấu hình trước khi chúng đến một slot triển khai.
GitHub Actions — xác thực tất cả cấu hình JSON
- name: Xác thực cấu hình JSON
run: |
echo "Đang xác thực các file cấu hình JSON..."
find . -name "*.json" -not -path "*/node_modules/*" | while read -r f; do
if ! jq . "$f" > /dev/null 2>&1; then
echo "::error file=$f::Cú pháp JSON không hợp lệ"
exit 1
fi
done
echo "Tất cả file JSON đều hợp lệ"Pre-commit hook — xác thực các file JSON đã stage
#!/usr/bin/env bash
set -euo pipefail
STAGED=$(git diff --cached --name-only --diff-filter=ACM | grep '\.json$' || true)
[ -z "$STAGED" ] && exit 0
for f in $STAGED; do
jq . "$f" > /dev/null 2>&1 || { echo "JSON không hợp lệ: $f"; exit 1; }
done
echo "Xác thực JSON đã qua"scripts/validate-json.sh, làm cho nó có thể thực thi với chmod +x scripts/validate-json.sh, sau đó tạo symlink: ln -s ../../scripts/validate-json.sh .git/hooks/pre-commit.Định Dạng Biến JSON và Heredoc trong Bash
Script shell thường xây dựng payload JSON động — từ biến môi trường, metadata git hoặc các giá trị được tính toán. Mẫu an toàn nhất là jq -n --arg / --argjson thay vì nội suy chuỗi, cái bị hỏng ngay khi một giá trị chứa dấu ngoặc kép hoặc dòng mới. Luôn đặt dấu ngoặc kép đôi cho các biến khi chuyển đến jq để ngăn việc tách từ trên khoảng trắng trong JSON.
Định dạng biến phản hồi API đã lưu
# Luôn trích dẫn "$API_RESPONSE" — khoảng trắng trong JSON sẽ phá vỡ mở rộng không có dấu ngoặc kép echo "$API_RESPONSE" | jq --indent 2 .
Xây dựng và định dạng payload với jq -n
payload=$(jq -n \
--arg env "production" \
--arg version "$(git describe --tags)" \
--argjson replicas 3 \
'{environment: $env, version: $version, replicas: $replicas}')
# Kiểm tra payload đã xây dựng
echo "$payload" | jq .
# Đăng lên API
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEPLOY_API_TOKEN" \
-d "$payload" \
"https://api.deployments.internal/v1/deploys"--arg luôn ràng buộc một giá trị chuỗi. --argjson phân tích giá trị như JSON trước, vì vậy bạn có thể truyền số, boolean, mảng và đối tượng mà không cần đặt dấu ngoặc kép bên trong biểu thức lọc.Định Dạng JSON trong Bash Mà Không Cài jq
Khi jq không khả dụng — image Docker tối thiểu, CI runner bị khóa, hoặc hệ thống mà bạn không thể cài đặt gói — module json.tool tích hợp của Python cung cấp cùng khả năng cốt lõi. Nó là một phần của thư viện chuẩn Python; nếu Python 3 được cài đặt, nó hoạt động không có phụ thuộc bổ sung.
# Định dạng từ file python3 -m json.tool config.json # Kiểm soát độ rộng thụt lề python3 -m json.tool --indent 2 config.json # Sắp xếp khóa theo thứ tự bảng chữ cái python3 -m json.tool --sort-keys config.json # Định dạng từ stdin (ví dụ: chuyển từ curl) curl -s https://api.deployments.internal/v1/status | python3 -m json.tool
python3 -m json.tool nghiêm ngặt hơn jq: nó từ chối dấu phẩy ở cuối, nhận xét và các phần mở rộng JSON5. Tính nghiêm ngặt này rất mong muốn cho xác thực cấu hình production nhưng có thể là điểm ma sát khi làm việc với JSON lỏng lẻo từ các công cụ bên thứ ba. Nó cũng không tạo ra đầu ra có màu, khiến việc kiểm tra terminal kém ergonomic hơn jq cho việc sử dụng tương tác.# Xác thực với mã thoát (ngữ nghĩa giống như jq)
python3 -m json.tool config.json > /dev/null && echo "hợp lệ" || echo "không hợp lệ"
# Xác thực chuỗi nội tuyến
echo '{"service":"payments-api","healthy":true}' | python3 -m json.tool > /dev/null
echo "Mã thoát: $?" # 0 = hợp lệĐầu Ra Terminal với Tô Sáng Cú Pháp
jq tô màu đầu ra theo mặc định — khóa màu xanh, chuỗi màu xanh lá, số màu trắng. Khi bạn cần tô sáng cú pháp JSON đầy đủ trong pager có thể cuộn, hoặc khi debug các phản hồi lồng nhau lớn trong phiên terminal, bat cung cấp trải nghiệm ergonomic nhất. Cả hai đều hữu ích để debug và kiểm tra tương tác; không cái nào nên được sử dụng khi ghi đầu ra vào file hoặc phản hồi API.
Cài đặt bat
# macOS brew install bat # Debian / Ubuntu (binary có thể tên là batcat — tạo alias nếu cần) apt-get install -y bat # alias bat=batcat # thêm vào ~/.bashrc nếu cần # Xác minh bat --version # bat 0.24.0
Xem file JSON với tô sáng cú pháp
# JSON được tô sáng cú pháp trong pager (nhấn q để thoát) bat config/app-config.json # Tắt phân trang — in trực tiếp ra terminal bat --paging=never config/app-config.json # Chuyển đầu ra jq qua bat để kiểm tra có màu jq '.database' infra/app-config.json | bat --language=json --paging=never
Đầu ra jq có màu trong pager có thể cuộn
# -C buộc màu ngay cả khi stdout không phải tty (ví dụ: khi chuyển đến less) jq -C . logs/deploy-response.json | less -R
bat / jq -C) để kiểm tra terminal và debug. Loại bỏ mã màu ANSI trước khi ghi vào file log hoặc chuyển đến các công cụ khác — dùng jq -M . (--monochrome-output) hoặc bat --plain.Làm Việc với File JSON Lớn trong Bash
Khi file JSON vượt quá 50–100 MB, việc tải vào bộ nhớ với chế độ mặc định của jq có thể chậm hoặc kích hoạt OOM trên các host bị giới hạn bộ nhớ (container Docker với giới hạn 512 MB, chẳng hạn). jq --stream phát ra các cặp path/value tăng dần khi đọc mà không đệm toàn bộ tài liệu. Đối với NDJSON (một đối tượng JSON mỗi dòng), jq có một cách tiếp cận gốc hiệu quả hơn.
Stream file JSON lớn với jq --stream
# --stream phát các cặp [path, scalar] khi jq đọc đầu vào # Trích xuất tất cả trường "status" từ kho lưu trữ log lớn mà không tải đầy đủ jq -c --stream 'if length == 2 and (.[0][-1] == "status") then .[1] else empty end' logs/archive-2026-03.json
NDJSON / JSON Lines — xử lý một đối tượng mỗi dòng
# NDJSON: một đối tượng JSON mỗi dòng — phổ biến trong Kafka exports, Fluentd và Logstash
# -R đọc dòng thô; fromjson? bỏ qua các dòng không phải JSON hợp lệ
jq -c -R 'fromjson? | {id: .request_id, status: .http_status, latency: .duration_ms}' logs/access-2026-03-13.ndjson > logs/summary.ndjson# Vòng lặp shell thay thế — hữu ích khi bạn cần xử lý lỗi mỗi dòng
while IFS= read -r line; do
echo "$line" | jq -c '{id: .request_id, status: .http_status}' 2>/dev/null || echo "BỎ QUA: dòng bị lỗi" >&2
done < logs/access-2026-03-13.ndjsonjq . file.json tiêu chuẩn sang --stream khi file lớn hơn 50–100 MB hoặc khi tiến trình chạy trong container có giới hạn bộ nhớ. Đối với pipeline NDJSON, ưu tiên jq -R 'fromjson?' hơn vòng lặp while read của shell — nó nhanh hơn đáng kể vì tránh tạo subshell mỗi dòng.Lỗi Thường Gặp
Vấn đề: Shell mở và cắt bớt file đầu ra trước khi jq đọc đầu vào. Nếu nguồn và đích là cùng một đường dẫn, jq đọc một file trống.
Giải pháp: Ghi vào file tạm mktemp trước, sau đó thay thế bản gốc một cách nguyên tử bằng mv.
jq --indent 2 . settings.json > settings.json
tmp=$(mktemp) && jq --indent 2 . settings.json > "$tmp" && mv "$tmp" settings.json
Vấn đề: Không có trình xử lý lỗi, script âm thầm tiếp tục với file đã định dạng trống hoặc bị thiếu khi JSON không hợp lệ — các bước tiếp theo sau đó thất bại với các lỗi khó hiểu.
Giải pháp: Thêm || { echo '...' >&2; exit 1; } sau mỗi lần gọi jq tạo ra đầu ra được sử dụng bởi bước sau.
jq . response.json > formatted.json
jq . response.json > formatted.json || { echo "JSON không hợp lệ trong response.json" >&2; exit 1; }Vấn đề: curl in thanh tiến trình vào stderr theo mặc định. Khi stderr được hợp nhất với stdout (ví dụ: trong subshell hoặc thu thập log), văn bản thanh tiến trình xuất hiện trong đầu vào của jq và gây ra lỗi phân tích.
Giải pháp: Luôn truyền -s (im lặng) cho curl khi chuyển đến jq. Dùng -v hoặc --fail-with-body riêng biệt nếu bạn cần đầu ra chẩn đoán.
curl https://api.payments.internal/config | jq .
curl -s https://api.payments.internal/config | jq .
Vấn đề: Cờ -r / --raw-output loại bỏ dấu ngoặc kép chuỗi JSON khỏi các giá trị chuỗi cấp cao nhất — nó không định dạng đối tượng hoặc mảng. Truyền -r . cho đầu vào đối tượng tạo ra cùng một đối tượng gọn gàng, không phải đầu ra được thụt lề.
Giải pháp: Dùng jq . (không có cờ -r) để định dạng. Giữ -r để trích xuất các giá trị chuỗi thuần túy như jq -r '.version' config.json.
jq -r . config.json
jq . config.json
jq vs python3 vs json_pp — So Sánh Nhanh
Chọn giữa các công cụ phụ thuộc vào những gì có sẵn trong môi trường của bạn và những gì bạn cần ngoài định dạng cơ bản:
Đối với hầu hết công việc bash scripting và CI/CD, jq là mặc định đúng — nó xác thực, định dạng, lọc và cung cấp mã thoát đáng tin cậy trong một binary duy nhất không có phụ thuộc runtime. Dùng python3 -m json.tool dự phòng khi bạn không thể cài đặt gói bổ sung và Python đã có sẵn.
Câu Hỏi Thường Gặp
Làm thế nào để định dạng file JSON tại chỗ bằng bash?
Đừng bao giờ chuyển hướng đầu ra của jq trở lại cùng một file — shell cắt bớt file trước khi jq đọc nó. Thay vào đó, hãy ghi vào file tạm trước, sau đó thay thế bản gốc một cách nguyên tử bằng mv.
tmp=$(mktemp) jq --indent 2 . config/app-config.json > "$tmp" && mv "$tmp" config/app-config.json echo "Định dạng tại chỗ thành công"
Làm thế nào để xác thực JSON trong script bash và thoát khi có lỗi?
Truyền hoặc chuyển file vào jq và chuyển hướng stdout đến /dev/null. Dùng || để bắt lần thoát khác không và hủy bỏ script. jq thoát với mã 1 cho bất kỳ lỗi phân tích nào, làm cho nó đáng tin cậy cho các cổng CI.
validate_json() {
local file="$1"
if jq . "$file" > /dev/null 2>&1; then
echo "✓ JSON hợp lệ: $file"
return 0
else
echo "✗ JSON không hợp lệ: $file" >&2
return 1
fi
}
validate_json infra/k8s/app-config.json || exit 1Làm thế nào để định dạng JSON trong bash mà không cài jq?
Dùng module json.tool tích hợp của python3 — nó đi kèm với mọi cài đặt Python tiêu chuẩn và tạo ra đầu ra thụt lề đúng với ngữ nghĩa mã thoát giống như jq.
# Định dạng từ file python3 -m json.tool config.json # Định dạng từ stdin (ví dụ: phản hồi curl) curl -s https://api.internal/status | python3 -m json.tool --indent 2
Làm thế nào để định dạng JSON từ phản hồi curl trong bash?
Luôn truyền -s (im lặng) cho curl để thanh tiến trình không làm hỏng đầu vào của jq. Chuyển stdout của curl trực tiếp vào jq.
DEPLOY_ID="dep_8f3a2b9c" curl -s \ -H "Authorization: Bearer $DEPLOY_API_TOKEN" \ "https://api.deployments.internal/v1/deploys/$DEPLOY_ID" \ | jq --indent 2 .
Làm thế nào để định dạng chỉ một phần của file JSON bằng jq?
Dùng biểu thức đường dẫn jq thay vì bộ lọc nhận diện (.) để trích xuất và định dạng một đối tượng hoặc mảng lồng nhau. Kết quả tự nó là JSON được định dạng.
# Định dạng chỉ khối cấu hình cơ sở dữ liệu
jq --indent 2 '.database' infra/app-config.json
# Định dạng + lọc mảng events chỉ ở cấp độ lỗi
jq '[.events[] | select(.level == "error") | {id, message, service}]' events.jsonjq trả về mã thoát nào cho JSON không hợp lệ?
jq thoát với mã 1 cho bất kỳ lỗi phân tích nào và cũng khi cờ -e / --exit-status được đặt và đầu ra là false hoặc null. Mã thoát 0 có nghĩa là JSON hợp lệ đã được phân tích và tạo ra đầu ra đúng. Mã thoát 5 có nghĩa là hệ thống gặp lỗi sử dụng.
# Kiểm tra mã thoát trực tiếp
echo '{"ok":true}' | jq . > /dev/null 2>&1; echo "exit: $?" # exit: 0
echo '{bad json}' | jq . > /dev/null 2>&1; echo "exit: $?" # exit: 1
# Cờ -e: thoát 1 nếu đầu ra là false/null
echo 'null' | jq -e . > /dev/null 2>&1; echo "exit: $?" # exit: 1Công Cụ Liên Quan
Các lựa chọn thay thế và bổ sung dựa trên trình duyệt cho định dạng JSON bash — hữu ích khi bạn cần giao diện trực quan, liên kết có thể chia sẻ hoặc đang làm việc bên ngoài terminal:
Nadia is a site reliability engineer who lives in the terminal. She writes Bash scripts that process logs, transform data, and orchestrate infrastructure across fleets of servers. She is a heavy user of jq, awk, and sed and writes about shell one-liners, text processing pipelines, data serialisation from the command line, and the practical Bash patterns that SREs reach for when speed matters more than elegance.
Erik is a DevOps engineer who has spent years writing and maintaining the shell scripts that hold CI/CD pipelines together. He writes about Bash best practices, portable POSIX shell, encoding and decoding in shell scripts, secret management from the command line, and the patterns that separate reliable automation scripts from brittle ones. He is a strong believer in making shell scripts readable and testable with tools like bats-core.