使用jq處理JSON數據(二)

之前的文章使用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);
    }

下面是jqjoin函數的使用:

 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源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章