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 的官方手冊 進行學習。
-----------------
我是良許,世界500強外企 Linux 開發工程師,專業生產 Linux 乾貨。歡迎關注我的公眾號「良許Linux」,回覆「1024」獲取最新最全的技術資料,回覆「入群」進入高手如雲技術交流群。