動機
在bash想處理json的好工具
basic
- .就是目前的input
- .<name>會取對應key的value
- {obj}[0]這是取array的第零項
- {obj}[i:j]這是slice第i項到第j-1項的array
- {obj}[]會iterate所有項目- array就是每個item
- obj就是無視key,把每個value走過一次
 
- [<expr>] {<expr>}分別做出array與json object
- <expr0> | <expr> as $var | <expr2>設定- $var成- <expr>的值,pipe後面的點是- <expr0>的值
例子
假設我們想把
[
    {
      "name":"Test Value",
      "timer":[
          { "datetime":"08/30/2017 16:33:35", "value":"625" },
          { "datetime":"08/30/2017 16:22:38", "value":"240" }
      ]
    },
    {
      "name":"Test Value 2",
      "timer":[
          { "datetime":"08/30/2017 16:07:38", "value":"432" },
          { "datetime":"08/30/2017 15:59:07", "value":"1355" }
      ]
    }
]
變成
[
  [
    "Test Value",
    "08/30/2017 16:33:35"
  ],
  [
    "Test Value",
    "08/30/2017 16:22:38"
  ]
]
[
  [
    "Test Value 2",
    "08/30/2017 16:07:38"
  ],
  [
    "Test Value 2",
    "08/30/2017 15:59:07"
  ]
]
所以要做的是
- 拿name
- iterate每個timer去拿datetime
- datetime與name組在一起
下面一步一步的code
- .[]- 先走每個值
 
- .[] | .name as $name- 取name
 
- .[] | .name as $name | .timer[]- 取timer走每個值
 
- .[] | .name as $name | .timer[] | .datetime- 取timer走每個值
 
- .[] | .name as $name | .timer[] | [$name, .datetime]- 把tiemr與datetime合起來
 
- .[] | .name as $name | [.timer[] | [$name, .datetime]]- 最後把timer的loop包起來
 
這個例子因為把不同level的資料和在一起,所以要變數把不同level的東西存好 才有辦法在後面需要時去用
所以怎麼看jq的咒語?
- 順著原本的json架構去看
- 分pipe去看現在的.是誰
- 遇到建構array或obj的部分要對好原本json的位置去看裡面是在建構什麼
faltten
如果要把
[
  [
    "Test Value",
    "08/30/2017 16:33:35"
  ],
  [
    "Test Value",
    "08/30/2017 16:22:38"
  ]
]
[
  [
    "Test Value 2",
    "08/30/2017 16:07:38"
  ],
  [
    "Test Value 2",
    "08/30/2017 15:59:07"
  ]
]
變成
[
  [
    "Test Value",
    "08/30/2017 16:33:35"
  ],
  [
    "Test Value",
    "08/30/2017 16:22:38"
  ]
  [
    "Test Value 2",
    "08/30/2017 16:07:38"
  ],
  [
    "Test Value 2",
    "08/30/2017 15:59:07"
  ]
]
可以用faltten
faltten(1)
這樣就能攤平一層
map, reduce
就是map與reduce,不過要注意.代表什麼
- map- 括號中的點是array或obj被走到的value
 
- reduce- 第一個點是整個input
- 第二個點是acc(累積的項目)
 
把[1,2,3]變成[11,12,13]
jq 'map(.+10)'
jq 'reduce .[] as $i ([]; . += [($i+10)])'
else
jq還能
- regex
- if-else- 可以判斷type,數字,字母,奇偶
 
- while
- 自訂function與recurse operator
- math(像三角函數)
- 許多builtin function