linux工具之jq
後端開發的工程師經常在linux下開發,當我們拿到一個json格式的數據時,如何有效對這個數據進行分析?我們可以採用python結合json庫來分析,但是linux有一個很好用的工具,讓我們可以方便地處理json文本,功能非常強大。
下載
參考官網說明
macOS:
brew install jq
Linux
sudo apt-get install jq
使用
數據準備
jq可以把json的文本輸出爲可讀形式,我準備了一份測試json數據,如下:
{
"name": "xueyuan",
"age": 21,
"birthday": "10th August",
"email": "[email protected]",
"skills" : [
"C/C++",
"Python",
"Golang",
"Node.js"
]
}
我使用python的json庫把它處理爲一個字符串,如下:
{"skills": ["C/C++", "Python", "Golang", "Node.js"], "age": 21, "birthday": "10th August", "name": "xueyuan", "email": "[email protected]"}
這個格式是我們在實際生產中經常看到的格式,比如我們使用curl請求一個接口,返回了一個json,比如我們在自己的項目中測試輸出了一個json數據,這種格式往往可讀性較差,我們需要進行處理後才能查看。
使用
要轉換成python處理前的那一種易讀形式很簡單,執行:
cat json2.data | jq '.'
#也可以寫作 cat json2.data | jq .
#不加引號,但是爲了標準最好寫上,因爲某些時候不加會有問題.
輸出
jq把數據轉換成易讀格式,還添加了顏色高亮說明,其中key和value使用了不同的顏色。
如果json數據很大,我們只想看其中某個字段數據,那麼使用如下語法:
#key是字段名稱
jq '.<key>'
測試
當某個字段是一個列表,jq可以對其進行切片
jq '.<list-key>[s:e]'
測試
切片支持圖中幾種格式,注意和python列表切片方式進行區分。
區別一下’.skills’和’.skills[]'兩種,可以看到前者輸出是一個列表,後者是非json格式的列表成員。
用法詳解
上一節是jq
的常用用法,這裏講解jq的具體原理。
jq從linux管道或者文件中獲取文本輸入,如果文本不滿足json格式,那麼jq會報錯,可以用這個方法來檢查一個文本是否滿足json檢查:
jq '.' json_file > /dev/null
jq使用filter來處理json文本,並輸出filter處理後的內容到標準輸出,filter是用來過濾滿足需求的字段的,比如最簡單的filter '.'
,這個表示無過濾策略,因此會輸出全部json文本。
key filter
'.<key>'
過濾滿足key的字段名,輸出這個key的值。
key-value filter
'<key>'
輸出key和value,區別key filter,如下
因爲key-value必須歸屬於某個對象,所以添加外層{}。
index filter
'.<list-key>[index]'
'.<list-key>[index1, index2]'
'.<list-key>[s:e]'
'.<list-key>[:e]'
'.<list-key>[s:]'
'.<list-key>[]'
數組索引和切片,用來操作列表元素。
嵌套層級filter
'.key1.key2.key3'
用於嵌套的json數據filter。
多個filter
'.key1, .key2, .key3'
使用英文單字節逗號分隔filter,用於在一個filter中過濾多個字段。
filter管道
'filter1 | filter2 | filter3'
example
jq '.contact | .phone | .home' people.json
由於大部分filter之後,輸出仍然是一個json數據,所以可以將filter通過管道連接。
重新組織filter後輸出的數據
有時候我們需要重新構造json的結構,比如去掉某一層嵌套,比如取某幾個字段組成一個新的json,這時候我們需要重新改變json的結構,我們可以使用[]
和{}
來重新組織json。
#把輸出組織成一個列表
jq '[filter1, filter2, filter3]' data.json
測試
#把輸出組織爲新的json對象
jq '{filter1, filter2, filter3}' data.json
測試
遞歸展開json結構
有時候我們需要在一個json裏邊查找某個字段,但是確不知道這個字段在哪個嵌套裏邊,如果嵌套很深那麼很難找到,jq可以把嵌套展開打平之後再查找。
#展開嵌套
jq '..' data.json
測試
展開之後結合管道再次filter可以查找key。
length filter
計算元素長度,對於對象,length表示對象裏的元素個數,對於string,length表示string字符數,對於列表,表示列表元素個數。
測試
keys filter
輸出全部的key,列表形式
測試
檢查某個key是否存在
如果輸入是一個對象,那麼對象的元素是以"key-value"形式存在的,使用
jq 'has("key-name")' data.json
檢查json對象是否含有某個key。
列表遍歷
jq支持使用map()或者map_values()遍歷列表,或者對象的值。
測試
刪除某個key
jq 'del(filter)' json.data
使用del()刪除filter描述的key-value。
瞭解更多
上一節只說明了jq比較常用的功能,實際上jq還有更多實用的filter,如果上述的功能還沒有滿足你的需求,你可以在jq項目地址上找到詳細說明。