我們都知道現在JSON是最常用的配置和數據交換格式之一,尤其是大量的系統API接口現在基本上都是以JSON格式顯示結果。JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。JSON獨立於語言的文本格式,具有典型的使C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等),JSON易於人閱讀和編寫。同時也易於機器解析和生成。
各種語言都有大量的JSON處理庫,比如fastjson,Json-lib,jsoniter,jackson,gson等,我們可以很方便就可以寫一個腳本獲取接口的Json信息,並通過這些類庫進行處理。
雖然如此,有些同學可能還是嫌寫腳本太麻煩,有沒有一種很簡單就能上手就用,用完就扔的JSON工具呢?答案是肯定的。這就是本文蟲蟲要給大家介紹的一個命令行工具jq,注意jq不是曾經流行的JS庫Jquery的縮寫。
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文件中的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。
jq可以通過在表達式中使用.鍵名來搜索值。
jq '.name' dog.json
CC
多個鍵搜索,中間用逗號分開:
jq '.breed,.name' dog.json
"金毛"
"CC"
可以將鍵名自定義:
jq '{"主人":.owner,"愛好":.likes}' dog.json
數組遍歷和查詢
入門部分我們說過,要搜索數組中的項目,請使用括號語法,索引從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!" 祝大家聖誕快樂!
數據轉換
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頁。
閱讀更多 蟲蟲安全 的文章