一、jq 簡介
JSON是一種輕量級的數據交換格式。其采用完全獨立於語言的文本格式,具有方便人閱讀和編寫,
同時也易於機器的解析和生成。這些特性決定了JSON格式越來越廣泛的應用於現代的各種系統中。
作為系統管理員,在日常的工作中無論是編輯配置文件或者通過http請求查詢信息,我們都不可避免的要處理JSON格式的數據。
jq 是一款命令行下處理JSON數據的工具。其可以接受標准輸入,命令管道或者文件中
的JSON數據,經過一系列的過濾器(filters)和表達式的轉后形成我們需要的數據結構並將結果輸出到標准輸出中。
jq的這種特性使我們可以很容易地在Shell腳本中調用它。
二、常用基礎命令
基礎表達式(Basic filters)是 jq 提供的基本過濾器,用來訪問 JSON 對象中的屬性。基礎表達式主要有以下幾種:
- ‘.’ 符號:單獨的一個’.’符號用來表示對作為表達式輸入的整個 JSON 對象的引用。
- JSON 對象操作:jq 提供兩種基本表達式用來訪問 JSON 對象的屬性:’.
’和’. ?’。正常情況下,這兩個表達式的行為相同:都是訪問對象屬性,如果 JSON 對象不包含指定的屬性則返回 null。區別在於,當輸入不是 JSON 對象或數組時,第一個表達式會拋出異常。第二個表達式無任何輸出。 - 數組操作:jq 提供三種基礎表達式來操作數組:
- 迭代器操作(‘.[]’). 該表達式的輸入可以是數組或者 JSON 對象。輸出的是基於數組元素或者 JSON 對象屬性值的 iterator。
- 訪問特定元素的操作(‘.[index]’或’.[attributename]’)。用來訪問數組元素或者 JSON 對象的屬性值。輸出是單個值
- 數組切片操作(‘.[startindex:endindex]’),其行為類似於 python 語言中數組切片操作。
- 表達式操作(‘,’和 ‘|’):表達式操作是用來關聯多個基礎表達式。其中逗號表示對同一個輸入應用多個表達式。管道符表示將前一個表達式的輸出用作后一個表達式的輸入。當前一個表達式產生的結果是迭代器時,會將迭代器中的每一個值用作后一個表達式的輸入從而形成新的表達式。例如’.[]|.+1’, 在這個表達式中,第一個子表達式’.[]’在輸入數組上構建迭代器,第二個子表達式則在迭代器的每個元素上加 1。
內置運算,jq 內部支持的數據類型有:數字,字符串,數組和對象(object)。並且在這些數據類型的基礎上, jq 提供了一些基本的操作符來實現一些基本的運算和數據操作。列舉如下:
- 數學運算。對於數字類型,jq 實現了基本的加減乘除(/)和求余(%)運算。對於除法運算,jq 最多支持 16 位小數。
- 字符串操作。jq 提供字符串的連接操作(運算符為’+’),字符串的復制操作(例如:’a’*3 結果為’aaa’),以及字符串分割操作(將字符串按照指定的分割符分成數組,例如”sas”/“s”的結果為[“”,”a”,””],而”sas”/“a”的結果為[“s”,”s”]。
1、命令行幫助
~/tmp$ jq -h
2、jq直接讀取文件
# xxx.JSON是我們要處理的JSON數據,我們可以直接將文件名傳給jq
~/tmp$ jq -r '.' xxx.JSON
# 或者由其他程序讀出文件內容,並傳給jq
~/tmp$ cat xxx.JSON | jq -r '.'
需要說明的是 jq 只能接受 well form 的 JSON 字符串作為輸入內容。也就是說輸入內容必須嚴格遵循 JSON 格式的標准。所有的屬性名必須是以雙引號包括的字符串。對象的最后一個屬性的末尾或者數組的最后一個元素的末尾不能有逗號。否則 jq 會拋出無法解析 JSON 的錯誤。
3、解析JSON,根據key獲取value
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq '.publications'
# 單個值獲取,解析不存在的元素,會返回null
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq '.publications[1].name'
# 嵌套解析,注意:json 數組的鍵命名必須為下划線"_",不能為"-",否則解析不了。解析不存在的元素,會返回null
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq 'keys'
# 內建函數-key,用來獲取JSON中的key元素
~/tmp$ curl 'https://www.jianshu.com/users/da1677475c27/publications?page=1&count=10'|jq 'has("publications")'
# 內建函數-has,用來是判斷是否存在某個key
4、對已有JSON進行翻倍
示例demo.json:
{
"code": 0,
"msg": "",
"store_name_list": [
{
"store_name": "gmail-demo-1"
}
]}
命令如下:
~/tmp$ demo=$(cat demo.json|jq '.store_name_list+=.store_name_list')
~/tmp$ echo "$demo"
結果如下:
{
"code": 0,
"msg": "",
"store_name_list": [
{
"store_name": "gmail-demo-1"
},
{
"store_name": "gmail-demo-1"
}
]}
