動機
在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