值得掌握的命令行JSON工具jq

我們都知道現在JSON是最常用的配置和數據交換格式之一,尤其是大量的系統API接口現在基本上都是以JSON格式顯示結果。JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。JSON獨立於語言的文本格式,具有典型的使C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等),JSON易於人閱讀和編寫。同時也易於機器解析和生成。

值得掌握的命令行JSON工具jq

各種語言都有大量的JSON處理庫,比如fastjson,Json-lib,jsoniter,jackson,gson等,我們可以很方便就可以寫一個腳本獲取接口的Json信息,並通過這些類庫進行處理。

值得掌握的命令行JSON工具jq

雖然如此,有些同學可能還是嫌寫腳本太麻煩,有沒有一種很簡單就能上手就用,用完就扔的JSON工具呢?答案是肯定的。這就是本文蟲蟲要給大家介紹的一個命令行工具jq,注意jq不是曾經流行的JS庫Jquery的縮寫。

值得掌握的命令行JSON工具jq

jq是一個出色的命令行JSON處理器,提供了用於查詢,操作和使用JSON文件的大量功能。而且作為一個命令行工具,可配合UNIX管道使用,單行腳本處理JSON。

安裝

jq是開源跨平臺的軟件,支持Linx,Mac OS和Windows,可通過應用包管理器、源碼形式安裝。

包管理安裝

Debian和Ubuntu系:sudo apt-get install jq

redhat系:sudo yum install jq 或 sudo dnf install jq

openSUSE:sudo zypper install jq

Arch:sudo pacman -Sy jq

Mac OS:使用Homebrew安裝,brew install jq

Windows:使用Chocolatey NuGet或者直接下載官方二進制包

chocolatey install jq

源碼安裝

git clone https://github.com/stedolan/jq.git

cd jq

autoreconf -i

./configure --disable-maintainer-mode

make

sudo make install

jq快速入門

為了方便以一個簡單例子開始。首先我們調用GitHub的API,獲取一個倉庫的commit歷史,並將其保存為example.json文件。

curl -o example.json 'https://api.github.com/repos/bollwarm/SecToolSet/commits'

要查看json內容最簡單的是使用.表達式,會打印json的原始內容。

jq '.' example.json

值得掌握的命令行JSON工具jq

json文件中的commit信息都是一個數組,其中一個commit可以使用.[x]操作,這和各個語言的數組操作也一樣。比如:

第一個commit為.[0],以零開頭。

jq '.[0]' example.json

| 操作符號是jq中的過濾器,過濾格式通過{...}來構建對象和屬性,可以嵌套訪問屬性,例如.commit.message

下面語句獲取第一個commit消息的commit.message和commit.committer.name並顯示message和name:

jq '.[0] | {message: .commit.message, name: .commit.committer.name}' example.json

[]中如果為空表示獲取所有的數組元素,獲取所有commit消息和提交者:

jq '.[] | {message: .commit.message, name: .commit.committer.name}' example.json

jq中的數據表示為JSON流:每個jq表達式對JSON流中的各個值操作,其輸出流可也包含任意數量的值。

通過僅用空格分隔JSON值即可對流進行序列化。這是cat顯示友好的格式。如果想要將結果要輸出作為數組形式的json格式,可以通過將過濾器用[]括住:

jq '[.[] | {message: .commit.message, name: .commit.committer.name}]' example.json

如果要獲取一個commit的多個父提交的URL,由於該字段為多個元素以數組形式顯示,如果直接使用.parents.html_url過濾則會下面的報錯:

jq: error (at example.json:2268): Cannot index array with string "html_url"

對該類字段過濾時候,需要使用[.parents[].html_url]的數組解析格式:

jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]' example.json

管道

我們在入門部分介紹了jq的基本使用和顯示。jq作為了一個標準的shell命令行工具,也是遵循UNIX POSIX原則的,比如管道。可以通過管道對接jq的數據輸入和輸出,這樣可以jq實現和其他工具進行交互非常。下面的管道中,cat將文件通過管道傳輸到jq,然後通過管道傳輸到less管道。這對於查看大型JSON文件非常有用。

cat example.json | jq '.' | less

當然用管道對接less著色就失效了,這是一個副作用。

對鍵和值過濾

為了找到鍵和值,jq可以根據鍵進行過濾並返回值。入門部分我們已經講了過濾鍵。我們再舉一個簡單例子,假設一個如下的JSON文檔保存為dog.json。

值得掌握的命令行JSON工具jq

jq可以通過在表達式中使用.鍵名來搜索值。

jq '.name' dog.json

CC

多個鍵搜索,中間用逗號分開:

jq '.breed,.name' dog.json

"金毛"

"CC"

可以將鍵名自定義:

jq '{"主人":.owner,"愛好":.likes}' dog.json

值得掌握的命令行JSON工具jq

數組遍歷和查詢

入門部分我們說過,要搜索數組中的項目,請使用括號語法,索引從0開始。

jq '.likes[1]' dog.json

"球球"

數組的多個元素也可能返回。

echo '["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",",","!"]'|jq '[.[12],.[4],.[17],.[17],.[24],.[26],.[2],.[7],.[17],.[8],.[18],.[19],.[12],.[0],.[18],.[27]]

結果:" MERRY,CHRISTMAS!" 祝大家聖誕快樂!

值得掌握的命令行JSON工具jq

數據轉換

jq不僅可以用於從JSON對象獲取值顯示,而且還可以用於JSON轉換為新的數據結構。比如:對dog.json 可以創建一個包含狗名和愛好的鍵,組成一個新數組。

jq '[.name,.likes[]]' dog.json

[

"CC",

"骨頭",

"球球",

"狗糧"

]

需要把JSON數據從一種結構轉移到另一種數據結構的數據轉換時,非常有用。

jq還可以對JSON對象中的數據進行操作。

echo '{"a": 1 , "b": 2}'|jq '.a+100'

101

其實上,+對字符串也是適用的,比如前面的聖誕快樂單行也可以為:

echo '["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",",","!"]'|jq '[.[12]+.[4]+.[17]+.[17]+.[24]+.[26]+.[2]+.[7]+.[17]+.[8]+.[18]+.[19]+.[12]+.[0]+.[18]+.[27]]'

結果:

[

"MERRY,CHRISTMAS!"

]

刪除JSON鍵

jq也支持從JSON對象中刪除鍵。刪除後輸出就不包含刪除key的JSON對象。刪除鍵使用del()函數,還是以dog.json為例:

jq 'del(.owner)' dog.json

結果中就不包括owner鍵了:

{

"name": "CC",

"breed": "金毛",

"age": "4",

"likes": [

"骨頭",

"球球",

"狗糧"

]

}

jq 'del(.)' dog.json

null

所有鍵都被刪了,所以上面結果為null。

值映射

jq可以映射值並在每個值上執行操作。在下面的示例中,數組中的每個鍵進行映射並做數值計算加2。

echo '[1,2,3,4,5,6]' |jq 'map(.+2)'

[

3,

4,

5,

6,

7,

8

]

總結

本文介紹了一個命令行下的json解析神器,更多文檔可以參考官方網站,可以託管倉庫的wiki頁。


分享到:


相關文章: