JSON 是一種輕量級的,不受語言約束的數據存儲格式,大部分編程語言都可以解析它,並且對編程人員也十分友好。我們在進行通訊/數據交互時,非常經常用到 JSON 格式。
但是,我們在進行數據存儲的時候,JSON 格式是以一行的數據進行存儲,閱讀起來的話也會有些困難。所以,為了更加便於閱讀,我們可以采用一些方法對 JSON 數據進行格式化。
在各種編程語言里,都會有一些相應的庫為我們解析 JSON 數據,比如 C 語言里有 cjson ,Python 里有 json.tool ,等等。
那在 Linux 平台下,有沒有一些工具可以不用編程,直接來格式化/解析 JSON 數據呢?
答案當然是肯定的,這個工具就是 jq
。
jq 是一款命令行下處理 JSON 數據的工具。其可以接受標准輸入,命令管道或者文件中的 JSON 數據,經過一系列的過濾器(filters)和表達式的轉化后形成我們需要的數據結構並將結果輸出到標准輸出中。jq 的這種特性使我們可以很容易地在 Shell 腳本中調用它。
jq 工具的安裝
有些發行版已經內置了 jq 這個工具,但有些還沒有。如果沒有內置這個工具的話,就需要我們手動安裝了。
各平台的安裝方法如下:
- Arch Linux 平台:
sudo pacman -S jq
- Debian, Ubuntu, Linux Mint 平台:
sudo apt-get install jq
- Fedora:
sudo dnf install jq
- OpenSUSE:
sudo zypper install jq
對於其它平台的安裝,需要查詢一下他們的官方安裝指導手冊。
使用 jq 工具格式化 JSON 數據
比如我們現在有以下 JSON 數據:
{"firstName":"Liangxu","lastName":"Yan","age":18,"address":{"streetAddress":"21 2nd Street","city":"Guangzhou","province":"Guangdong","postalCode":"510655"},"phoneNumber":[{"type":"home","number":"020 555-1234"},{"type":"company","number":"020 555-4567"}],"gender":{"type":"male"}}
看起來很暈是吧?也不方便閱讀是吧?
我們先將這個文件保存為 liangxu.json 文件,然后再用 jq 工具格式化一下,使它更便於我們閱讀:
cat liangxu.json | jq '.'
輸出結果:
{
"firstName": "Liangxu",
"lastName": "Yan",
"age": 18,
"address": {
"streetAddress": "21 2nd Street",
"city": "Guangzhou",
"province": "Guangdong",
"postalCode": "510655"
},
"phoneNumber": [
{
"type": "home",
"number": "020 555-1234"
},
{
"type": "company",
"number": "020 555-4567"
}
],
"gender": {
"type": "male"
}
}
'.' 是 jq 工具的最簡單表達式,它不改變輸入,但可以將其優美地輸出,便於閱讀和理解。
在以下的案例中,我們均以此數據作為解析對象。
使用 jq 工具解析特定字段
在以上那個示例 JSON 數據中,假如我們想要解析出 address 這個字段,我們可以這樣使用 jq 工具:
jq .address liangxu.json
輸出結果:
{
"streetAddress": "21 2nd Street",
"city": "Guangzhou",
"province": "Guangdong",
"postalCode": "510655"
}
接下來,我們來進一步解析地址中的郵編,我們配合管道來進行。
cat liangxu.json | jq .address.postalCode
輸出結果:
"510655"
請注意,使用 jq 命令時,過濾器是大小寫敏感的,所以你在解析字段時,必須嚴格跟原字段一樣,否則就無法進行解析。
使用 jq 工具解析中數組中的元素
在 JSON 數據中,數組是以方括號括起來的一組元素。如果要解析數組中的元素,我們就需要用到數組里的下標。
在示例 JSON 數據中,phonenumber 這個字段所存儲的內容是一個數組,如果我們要獲得這個數組里的所有元素,我們只需加上一對方括號即可,如下命令:
jq .phoneNumber[] liangxu.json
輸出結果:
{
"type": "home",
"number": "020 555-1234"
}
{
"type": "company",
"number": "020 555-4567"
}
如果我們要過濾出數組里的第一個元素,我們可以加上下標 [0] :
jq .phoneNumber[0] liangxu.json
輸出結果:
{
"type": "home",
"number": "020 555-1234"
}
jq 工具的內建函數
jq 工具為我們提供了很多內建函數,這里介紹其中的兩個:keys 和 has 。
- keys
keys 是用來獲取 JSON 中的 key 元素的,查找 JSON 數據中所有的鍵。
cat liangxu.json | jq 'keys'
輸出結果:
[
"address",
"age",
"firstName",
"gender",
"lastName",
"phoneNumber"
]
- has
has 是用來是 JSON 數據中判斷是否存在某個 key,它的輸出結果是 true 或 false 。
cat liangxu.json | jq 'has("alvin")'
輸出結果:
false
小結
以上所介紹的是 jq 工具很基本的用法,jq 不僅能夠滿足一般性的常見需求,更包含運算、內置函數、條件比較、 變量聲明、自定函數等強大功能。對此感興趣的朋友,不妨通過 jq 的官方手冊 進行學習。
公眾號:良許Linux
