JQ

Reference1

Reference2

Reference3

jq 语法

jq 是 stedolan 开发的一个轻量级的和灵活的命令行JSON处理器
jq 用于处理JSON输入,将给定过滤器应用于JSON文本输入,并在标准输出上将过滤器的结果生成为JSON。

yum install jq

jq [options] <jq filter> [file...]
jq [options] --args <jq filter> [strings...]
jq [options] --jsonargs <jq filter> [JSON_TEXTS...]

-c               紧凑而不是漂亮的输出;
-n               使用`null`作为单个输入值;
-e               根据输出设置退出状态代码;
-s               将所有输入读取(吸取)到数组中;应用过滤器;
-r               输出原始字符串,而不是JSON文本;
-R               读取原始字符串,而不是JSON文本;
-C               为JSON着色;
-M               单色(不要为JSON着色);
-S               在输出上排序对象的键;
--tab            使用制表符进行缩进;
--arg a v        将变量$a设置为value<v>;
--argjson a v    将变量$a设置为JSON value<v>;
--slurpfile a f  将变量$a设置为从<f>读取的JSON文本数组;
--rawfile a f    将变量$a设置为包含<f>内容的字符串;
--args           其余参数是字符串参数,而不是文件;
--jsonargs       其余的参数是JSON参数,而不是文件;
--               终止参数处理;

查询

# .: 以漂亮的方式输出
$ echo '{ "foo": { "bar": { "baz": 123 } } }' | jq '.'
{
  "foo": {
    "bar": {
      "baz": 123
    }
  }
}

# .foo, .foo.bar, .foo?: 获取一个键的值
$ echo '{"foo": 42, "bar": "less interesting data"}' | jq '.foo'
42

# .[], .[]?, .[2], .[10:15]: 数组运算
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[]'
{
  "name": "JSON",
  "good": true
}
{
  "name": "XML",
  "good": false
}

$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[1]'
{
  "name": "XML",
  "good": false
}

# length: 计算一个值的长度
$ echo '[[1,2], "string", {"a":2}, null]' | jq '.[] | length'                                  
2
6
1
0

# keys: 取出数组中的键
$ echo '{"abc": 1, "abcd": 2, "Foo": 3}' | jq 'keys'                                        
[
  "Foo",
  "abc",
  "abcd"
]

# ,: 使用多个过滤器
$ echo '{ "foo": 42, "bar": "something else", "baz": true}' | jq '.foo, .bar' 
42
"something else"

# |: 通过管道将一个过滤器的输出当做下一个过滤器的输入
$ echo '[{"name":"JSON", "good":true}, {"name":"XML", "good":false}]' | jq '.[] | .name'                                                 
"JSON"
"XML"

# select(foo): 如果foo返回true,则输入保持不变
$ echo '[1,5,3,0,7]' | jq 'map(select(. >= 2))'                                                    
[
  5,
  3,
  7
]

# map(foo): 每个输入调用过滤器
$ echo '[1,2,3]' | jq 'map(.+1)'
[
  2,
  3,
  4
]

取某一个特定值

[root@dell-per740-92 ynl]# cat device.json 
[
{
  "clock-id": 5799633565437388592,
  "id": 0,
  "lock-status": "locked-ho-acq",
  "mode": "automatic",
  "mode-supported": ["automatic"],
  "module-name": "ice",
  "type": "eec"},
 {
  "clock-id": 5799633565437388592,
  "id": 1,
  "lock-status": "locked-ho-acq",
  "mode": "automatic",
  "mode-supported": ["automatic"],
  "module-name": "ice",
  "type": "pps"}
]

[root@dell-per740-92 ynl]# cat device.json | jq .[] | jq 'select(.id ==0)'
{
  "clock-id": 5799633565437388592,
  "id": 0,
  "lock-status": "locked-ho-acq",
  "mode": "automatic",
  "mode-supported": [
    "automatic"
  ],
  "module-name": "ice",
  "type": "eec"
}

# print parent value
[root@dell-per740-92 ynl]# cat test.json 
{
    "FOO": {
        "name": "Donald",
        "location": "Stockholm"
    },
    "BAR": {
        "name": "Walt",
        "location": "Stockholm"
    },
    "BAZ": {
        "name": "Jack",
        "location": "Whereever"
    }
}
[root@dell-per740-92 ynl]# cat test.json | cat test.json | jq -c 'to_entries[] | select (.value.location == "Stockholm") | [.key, .value.name]'
["FOO","Donald"]
["BAR","Walt"]
[root@dell-per740-92 ynl]# jq -c 'to_entries[] | select (.value.location == "Stockholm") | [.key, .value.name]' test.json 
["FOO","Donald"]
["BAR","Walt"]

创建

# jq -n {a:1}
{
  "a": 1
}
[root@test-dhcp ~]# jq -n '{a:"test"}'
{
  "a": "test"
}

合并

# jq -n '{a:"test"} + {b:2}'
{
  "a": "test",
  "b": 2
}

# jq -n '{a:"test"} + {b:2} + {c:"testc"}'
{
  "a": "test",
  "b": 2,
  "c": "testc"
}

删除

[root@test-dhcp ~]# cat test.json 
{"a": "test","b": 2, "c": "testc"}
[root@test-dhcp ~]# cat test.json |jq .
{
  "a": "test",
  "b": 2,
  "c": "testc"
}
[root@test-dhcp ~]# cat test.json |jq 'del(.b)'
{
  "a": "test",
  "c": "testc"
}

更新

[root@test-dhcp ~]# cat test.json 
{"a": "test","b": 2, "c": "testc"}
[root@test-dhcp ~]# cat test.json |jq '.b="testb"'
{
  "a": "test",
  "b": "testb",
  "c": "testc"
}
[root@test-dhcp ~]# cat test.json |jq '. + {d:4}'
{
  "a": "test",
  "b": 2,
  "c": "testc",
  "d": 4
}
[root@test-dhcp ~]# cat test.json |jq '. + {d:4}' |jq '.d={dd:5}'
{
  "a": "test",
  "b": 2,
  "c": "testc",
  "d": {
    "dd": 5
  }
}

查看数据类型

[root@test-dhcp ~]# echo "{}" |jq -r type
object
[root@test-dhcp ~]# echo '[0, false, [], {}, null, "hello"]' |jq 'map(type)'
[
  "number",
  "boolean",
  "array",
  "object",
  "null",
  "string"
]

查询数组中的值

[root@test-dhcp ~]# echo [1,2,3] |jq .[1]
2
[root@test-dhcp ~]# echo [1,2,3] |jq .[2]
3

查询数组长度

[root@test-dhcp ~]# echo [1,2,3,9] |jq '.|length'
4
[root@test-dhcp ~]# echo [1,2,3] |jq '.|length'
3

数组相加

[root@test-dhcp ~]# echo [1,2,3] |jq '. + [4,5,6]'
[
  1,
  2,
  3,
  4,
  5,
  6
]

高级查询

[root@test-dhcp ~]# echo [1,2,3] | jq 'map(select(. >= 2))'
[
  2,
  3
]
[root@test-dhcp ~]# echo [1,2,3] | jq 'map(select(. == 2))'
[
  2
]
[root@test-dhcp ~]# echo [1,2,3] | jq 'map(select(. != 2))'
[
  1,
  3
]
[root@test-dhcp ~]# cat test.json 
[
  {
    "id": "0",
    "model": "Intel(R)Xeon(R)CPUE5-2620v4@2.10GHz"
  },
  {
    "id": "1",
    "model": "Intel(R)Xeon(R)CPUE5-2620v4@2.10GHz"
  }
]
[root@test-dhcp ~]# cat test.json |jq .[].model
"Intel(R)Xeon(R)CPUE5-2620v4@2.10GHz"
"Intel(R)Xeon(R)CPUE5-2620v4@2.10GHz"

类型转换

[root@test-dhcp ~]# echo '["a","b,c,d","e"]' |jq 'join(",")'
"a,b,c,d,e"
[root@test-dhcp ~]# echo '["a","b,c,d","e",1]' |jq 'join(",")'
jq: error (at <stdin>:1): string (",") and number (1) cannot be added
[root@test-dhcp ~]# cat test.json 
liuxin,30,male
jiaweiqiang,29,femal
[root@test-dhcp ~]# jq -R 'split(",")|{"name":.[0],"age":.[1],"sex":.[2]}' ./test.json 
{
  "name": "liuxin",
  "age": "30",
  "sex": "male"
}
{
  "name": "jiaweiqiang",
  "age": "29",
  "sex": "femal"
}
[root@test-dhcp ~]# cat test.json 
{
  "name": "liuxin",
  "age": "30",
  "sex": "male"
}
{
  "name": "jiaweiqiang",
  "age": "29",
  "sex": "femal"
}
[root@test-dhcp ~]# cat test.json |jq . -c
{"name":"liuxin","age":"30","sex":"male"}
{"name":"jiaweiqiang","age":"29","sex":"femal"}