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 # "Leanne Graham" curl -s https://jsonplaceholder.typicode.com/users | jq .[0].address.street # "Kulas Light"
使用 jq 的一些參數也可以達成 json encode 的功能:
test
#!/bin/bash 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" # {"name": "chan"} is valid format JSON='{"name":}' json_validator "$JSON" # {"name":} is invalid format
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
部分會讓沒搜到的結構不輸出,因此最終只會跑出我們要的結果。