之前的文章使用jq處理JSON數據(一)中,我分享了jq
工具的基本用法。今天開始分享jq
的高階使用,包括管道符、函數以及格式轉換。
管道符和函數
在這個章節中中,將分享jq
更多過濾JSON
數據的方法。
使用|
運算符,我們可以結合兩個過濾器。它的工作原理與Unix
系統管道符類似。左邊的過濾器的輸出傳遞到右邊的過濾器。
請注意:.name.first
與.name | .first
使用結果是完全相同的,就將JSON
數據中.name
節點數據傳遞到第二個過濾器,然後選擇.first
。
管道可以跟其他功能組合。例如,我們可以使用keys
函數來獲取JSON
數據某個節點的鍵集合:
✘ fv@FunTester ~/Downloads cat FunTester.json | jq '. | keys'
[
"article",
"name"
]
fv@FunTester ~/Downloads
使用length
函數,我們可以獲得數組中元素的數量長度:
fv@FunTester ~/Downloads cat FunTester.json | jq '. | keys | length'
2
length
函數的輸出取決於輸入元素:
-
如果傳遞了字符串,則返回字符 length
-
對於數組,返回元素個數 length
或者size
-
對於對象,返回鍵-值對的 size
我們還可以將length
函數跟運算符組合使用:
fv@FunTester ~/Downloads cat FunTester.json | jq '. | keys | length > 1'
true
還有一個更厲害的篩選函數select
,有點MySQL
數據庫的意味。
✘ fv@FunTester ~/Downloads cat FunTester.json | jq '.article[] | select (.author == "tester2")'
{
"author": "tester2",
"title": "performanceTest"
}
select
函數後面跟的boolean
表達式還可以是其他很多種形式,這裏不再意義演示。
轉換格式
這個章節,我將分享一些使用jq
將原來JSON
數據組合轉換其他格式的技巧。
先來拼接一個簡單的JSON
格式數據:
fv@FunTester ~/Downloads cat FunTester.json | jq '{(.article[0].title): "FunTester"}'
{
"ApiTest": "FunTester"
}
這個例子中,首先我創建了一個只有一對鍵值對的JSON
對象,其中key
是從原來數據中取到的,表達式爲(.article[0].title)
,這個在上一篇文章中已經講過了,這裏不多說。value
我直接賦值爲FunTester
。
請注意,jq
表達式中,要想構建新的JSON
格式數據,如果key
爲表達式時,需要用()
括起來,但是value
是表達式的時候就不用了,僅限於單表達式,下面會介紹一些複合表達式不適用。下面這個例子演示value
的值是表達式的時候。
fv@FunTester ~/Downloads cat FunTester.json | jq '{(.article[0].title): .article}'
{
"ApiTest": [
{
"author": "tester1",
"title": "ApiTest"
},
{
"author": "tester2",
"title": "performanceTest"
}
]
}
下面介紹一下map
函數,map
函數用於通過提取某個節點下的某個value
值集合來組成新的數組。
✘ fv@FunTester ~/Downloads cat FunTester.json | jq '{(.article[0].title): (.article | map(.title))}'
{
"ApiTest": [
"ApiTest",
"performanceTest"
]
}
我們再通過一個實驗來探索一下map
函數的用法:
fv@FunTester ~/Downloads cat FunTester.json | jq '{(.article[0].title): (.article | map("FunTester1","FunTester2"))}'
{
"ApiTest": [
"FunTester1",
"FunTester2",
"FunTester1",
"FunTester2"
]
}
這裏我將map
函數中的參數寫成了兩個常量,最終的輸出結果是兩遍的常量,所以map
函數執行了兩遍,是跟前面的數組的長度一致的,而且沒有去重功能。
接下來分享另外一個函數join
,這個跟Java
中拼接字符串的StringUtils.join()
非常相似。下面是Java
用的使用Demo
。
public static String join(String text, String separator) {
return StringUtils.join(ArrayUtils.toObject(text.toCharArray()), separator);
}
下面是jq
中join
函數的使用:
fv@FunTester ~/Downloads cat FunTester.json | jq '{(.article[0].title): (.article | map("FunTester1","FunTester2") | join("-"))}'
{
"ApiTest": "FunTester1-FunTester2-FunTester1-FunTester2"
}
我用連接符,將剛纔使用map
函數構建的數組連接起來。
FunTester,騰訊雲年度作者、Boss直聘簽約作者,GDevOps官方合作媒體,非著名測試開發。
本文分享自微信公衆號 - FunTester(NuclearTester)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。