JSON 格式的應用現在已經隨處可見了,目前使用的程式語言都有相關支援的套件,如果要在 Linux 底下操作的話有一個非常好用的工具叫 jq,下面來展示應用範例
應用網址:https://jsonplaceholder.typicode.com/users
curl -s https://jsonplaceholder.typicode.com/users | jq .
我們會得到格式漂亮的結果
| [ |
| { |
| "id": 1, |
| "name": "Leanne Graham", |
| "username": "Bret", |
| "email": "Sincere@april.biz", |
| "address": { |
| "street": "Kulas Light", |
| "suite": "Apt. 556", |
| "city": "Gwenborough", |
| "zipcode": "92998-3874", |
| "geo": { |
| "lat": "-37.3159", |
| "lng": "81.1496" |
| } |
| }, |
| "phone": "1-770-736-8031 x56442", |
| "website": "hildegard.org", |
| "company": { |
| "name": "Romaguera-Crona", |
| "catchPhrase": "Multi-layered client-server neural-net", |
| "bs": "harness real-time e-markets" |
| } |
| } |
| ] |
而 jq 可以做 node 的搜尋,以上面那个例子
| curl -s https://jsonplaceholder.typicode.com/users | jq .[0].name |
| curl -s https://jsonplaceholder.typicode.com/users | jq .[0].address.street |
使用 jq 的一些參數也可以達成 json encode 的功能:
test
| |
| |
| NAME=$1 |
| AGE=$2 |
| |
| JSON_STRING=$(jq -n \ |
| --arg name "$NAME" \ |
| --arg age "$AGE" \ |
| '{name: $name, age: $age}') |
| |
| echo $JSON_STRING |
./test chan 40 # { "name": "chan", "age": "40" }
jq 沒有驗證 json format 的功能,但我們可以利用一些 shell script 的特性辦到這件事
| #!/bin/bash |
| |
| function json_validator() { |
| echo $1 | jq . &> /dev/null |
| |
| if [[ $? == 0 ]]; then |
| echo "$1 is valid format" |
| else |
| echo "$1 is invalid format" |
| fi |
| } |
| |
| JSON='{"name": "chan"}' |
| json_validator "$JSON" |
| |
| |
| JSON='{"name":}' |
| json_validator "$JSON" |
| |
jq 也可以使用自定義模組,在 ~/.jq
裡面可以將一些複雜但常用的內容先寫好
| def blurry($f): |
| ($f | ascii_upcase) as $ucf |
| | to_entries[] |
| | select((.key|ascii_upcase) | startswith($ucf)) |
| | .value; |
| |
| |
| def very_blurry($f): |
| ($f | ascii_upcase) as $ucf |
| | to_entries[] |
| | select(.key | ascii_upcase | index($ucf)) |
| | .value; |
這樣的話像搜尋 docker 的 config 的話就非常好用,像是 docker inspect test | jq '.. | blurry("config")?' | objects
搜尋語法
| $ jq 'map(select(.id=="1234"))' |
| $ jq 'map(select(.id|index("1234")))' |
| $ jq 'map(select(.id|contains("1234")))' |
| $ jq 'map(select(.id|test("1234";"i")))' |
| $ jq 'map(select(.id|match("1234";"i")))' |
docker inspect 出來的結果是 json format,假設我們今天要找 LogPath
,但不記得他的層級的話,有個語法可以針對該 key 找出資料。
docker inspect <container_id> | jq -r '.. | .LogPath? // empty'
-r
是輸出 raw data 好複製,// empty
部分會讓沒搜到的結構不輸出,因此最終只會跑出我們要的結果。