2014年1月20日 星期一

使用jq來解析JSON格式的資料

    JSON(JavaScript Object Notation)是一種輕量級的資料交換語言,以文字為基礎,且易於讓人閱讀;它最開始被廣泛的應用於WEB應用的開發,而近年來隨著web 2.0以及手機APP風潮的興盛,json由於比XML更加小巧,以及瀏覽器的內建快速解析支援,使得其更適用於網路資料傳輸領域。

    此外,在比較缺乏資料庫支援的unix shell環境,若使用json來作為資料查詢與交換,對於開發更複雜的應用或功能來說,會更加的便利。

安裝與測試環境準備
    Linux也有工具可支援解析JSON格式的資料,就像本文要介紹的jq;您可以透過EPEL使用yumapt-get等工具來安裝,或者直接到http://stedolan.github.io/jq/ 下載。(實際上並不需要安裝,jq本身是binary的執行檔,下載後便可執行)


    我們先準備一個json檔案來試看看,請將下方範例儲存為json.txt:
{
       "name": "Google",
       "location":
               {
                       "street": "1600 Amphitheatre Parkway",
                       "city": "Mountain View",
                       "state": "California",
                       "country": "US"
               },
       "employees":
               [
                       {
                               "name": "Michael",
                               "division": "Engineering"
                       },
                       {
                               "name": "Laura",
                               "division": "HR"
                       },
                       {
                               "name": "Elise",
                               "division": "Marketing"
                       }
               ]
}

實際測試使用
  1. 我們輸入如下指令:
[chtseng@itgallery ~]$ cat json.txt | jq '.name'
"Google"

        ‘.name’表示要解析第一層name的值,因此會傳回Google。

  1. 如果要解析的是location下的city,則要寫成’ .location.city’
[chtseng@itgallery ~]$ cat json.txt | jq '.location.city'
‘Mountain View’

  1. 如果要解析的是employees下的第一筆name值,則要寫成’ .employees[0].name’
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[0].name '
‘Michael’

  1. ‘.[]’表示所有的json內容
cat json.txt | jq '.[]'
[
 {
   ‘division’: ‘Engineering’,
   ‘name’: ‘Michael’
 },
 {
   ‘division’: ‘HR’,
   ‘name’: ‘Laura’
 },
 {
   ‘division’: ‘Marketing’,
   ‘name’: ‘Elise’
 }
]
{
 ‘country’: ‘US’,
 ‘state’: ‘California’,
 ‘city’: ‘Mountain View’,
 ‘street’: ‘1600 Amphitheatre Parkway’
}
‘Google’

  1. ‘.employees[0]’表示employees第一筆內容
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[0]'
{
 ‘division’: ‘Engineering’,
 ‘name’: ‘Michael’
}

  1. ‘.employees[0:1]’你會發現傳回的值和’.employees[0]’相同,這是因為[0:1] :後方的數值表示在該數之前,而不包含該數本身,所以[0:1]代表的意思是,從第1筆到第2筆之前,但不包含第2筆的資料。
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[0:1]'
[
 {
   ‘division’: ‘Engineering’,
   ‘name’: ‘Michael’
 }
]

  1. ‘.employees[0:2]’所以[0:2]代表的意思是從第1筆到第3筆之前,但不包含第3筆的資料,所以總共只會傳回2筆資料。
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[0:2]'
[
 {
   ‘division’: ‘Engineering’,
   ‘name’: ‘Michael’
 },
 {
   ‘division’: ‘HR’,
   ‘name’: ‘Laura’
 }
]

  1. ‘.employees[-1:]’表示從最後方數回來的第1筆資料。
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[-1:]'
[
 {
   ‘division’: ‘Marketing’,
   ‘name’: ‘Elise’
 }
]

  1. ‘.employees[-2:3]’那麼-2:3呢?就表示從最(後方數回來的第2筆資料)到(由前方數起的第4筆資料)。
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[-2:3]'
[
 {
   ‘division’: ‘HR’,
   ‘name’: ‘Laura’
 },
 {
   ‘division’: ‘Marketing’,
   ‘name’: ‘Elise’
 }
]]

  1. Jq的解析也可以用|符號來串接處理,例如:
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[] | .name'
‘Michael’
‘Laura’
‘Elise’

  1. Jq可以作一些運算,例如下方範例,將姓名後方加上 ‘_test’:
[chtseng@itgallery ~]$ cat json.txt | jq '.employees[] | .name + ‘_test’'
‘Michael_test’
‘Laura_test’
‘Elise_test’

  1. 除了將json內容導向jq來處理,也可以用如下的方式傳入json檔案
[chtseng@itgallery ~]$ jq '.employees[] | .name + ‘_test’' json.txt
‘Michael_test’
‘Laura_test’
‘Elise_test’

1 則留言: