@cdmonkey
2024-06-28T13:58:20.000000Z
字数 4309
阅读 67
命令总结
jq - Command-line JSON processor
jq [options...] filter [files...]
注意:指令只能接受标准 JSON 字符串,输入内容必须严格遵守 JSON 格式标准,属性名必须要使用双引号。
这是一个命令行下的 Json 字符串处置工具,就像 sed
对于文本一样,jq
对应着 Json 文件,这个命令可用不同方案转换 Json 内容。它能够接受文本输入,缺省情况下,它能够从标准输入读入 Json 流。通过同管道进行组合可非常方便的处置 Json。
不用编译安装,直接下载可执行文件就行。
[root@es01 tools]# mv jq-linux64 /usr/local/bin/
[root@es01 tools]# mv /usr/local/bin/jq-linux64 /usr/local/bin/jq
[root@es01 tools]# chmod +x /usr/local/bin/jq
# 其实还可以直接使用 yum 安装:
[root@es01 ~]# yum install -y jq
常用选项:
-c | 紧凑输出,就是输出为一行
-n | 使用 null 作为单个输入值
-e | 根据输出设置退出状态代码
-s | 读入所有输入至数组中,对它进行过滤
-r | 输出原始字符串,而不是 JSON 文本
-R | 读入原始字符串,而不是 JSON 文本
-C | 进行着色
-M | 单色显示,不进行着色
-S | 输出时对键进行排序
--tab | 使用制表符进行缩进
直接处置文件:
# Use this Json file:
[root@es01 ~]# cat input.json
{"name": "cdmonkey", "city": "Beijing"}
==============
[root@es01 ~]# jq '.' input.json
{
"name": "cdmonkey",
"city": "Beijing"
}
注意:jq
只能接受标准 JSON 内容,输入之文件内容必须要严格遵守 JSON 标准,所有属性名必须是双引号字符串。
格式化 JSON
[root@es01 ~]# echo '{"name": "cdmonkey", "city": "Beijing"}' | jq .
{
"name": "cdmonkey",
"city": "Beijing"
}
将 JSON 文件内容压缩为一行:
[root@es01 ~]# cat target.json
[
{
"targets": ["10.30.8.138:9273"],
"labels": { "alias": "PBS-Zookeeper01" }
},
{
"targets": ["10.30.8.139:9273"],
"labels": { "alias": "PBS-Zookeeper02" }
}
]
[root@es01 ~]# jq -c . target.json
[{"targets":["10.30.8.138:9273"],"labels":{"alias":"PBS-Zookeeper01"}},{"targets": ...
获得特定文本:
[root@es01 ~]# cat input.json | jq '.name'
"cdmonkey"
# Return null if key does not exist:
[root@es01 ~]# cat input.json | jq '.age'
null
注意:key 的书写支持 .key.key
这样级联访问。
还可使用函数:
[root@es01 ~]# echo "[1,2,3,4]" | jq -rc 'map(.+1)'
[2,3,4,5]
[root@es01 ~]# echo "[1,2,3,4]" | jq -rc 'map(select(.>2))'
[3,4]
[root@ZF-YW-PROMETHEUS-55aee4 files]# jq '.[]' zf-30-10.yml|jq -r '.targets[0]'
10.30.10.1:9273
10.30.10.3:9273
10.30.10.4:9273
10.30.10.5:9273
...
找出所有地址及其对应别名:
jq '.[]' 100.yml|jq -r '.targets[0], .labels.alias'
[root@elk-fb ~]# echo '{"name": "cdmonkey", "city": "Beijing"}' | \
jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]"
name=cdmonkey
city=Beijing
还能够这样:
[root@elk-fb ~]# cat data.json
{
"SITE_DATA": {
"URL": "suixingpay.com",
"AUTHOR": "cdmonkey",
"CREATED": "2020-09-15"
}
}
jq -r '.SITE_DATA | to_entries | .[] | .key + "=\"" + .value + "\""' data.json
URL="suixingpay.com"
AUTHOR="cdmonkey"
CREATED="2020-09-15"
echo '{"name": "cdmonkey", "city": "Beijing"}' | jq -r '[.name,.city]|join(" lives in ")'
cdmonkey lives in Beijing
就是依据某个属性值查找出相应对象。
实例:
COMMAND_TEMP="jq '.[]|select(.targets[0]==\"${IP}:9273\")' ${json_file} |jq '.labels.alias'"
ALIAS_TEMP=$(eval ${COMMAND_TEMP})
ALIAS=$(echo ${ALIAS_TEMP}|sed 's/\"//g')
# Then use the test function to compare an attribute to a regex
jq '.[] |select(.labels.alias|test("二维码.*通道"))' zf-30-1.yml|jq '.targets[0]'
# 改造一下:
jq '.[] |select(.labels.alias|test("二维码.*通道")) |.targets[0]' zf-30-10.yml
jq '.[] |select(.labels.application=="QRCODE-AQUERY")' 10.yml
jq '.[] |select(.labels.application=="QRCODE-AQUERY")|.targets[0]' 10.yml
说明:老版本 jq
没有 test 函数,需要 yum 升级至最新版。
jq '.[] |select(.labels.alias|test("商业*")) |.labels.alias, .labels.application' 11.yml
curl -s https://nd.suixingpay.com/api/resources/noToken/resources/monitor/suixingpay/10.30.5|jq -r '.[].targets[0]'
jq '.[]' 10.yml |jq --indent 4 '.labels += {
"cpu_load": 200,
"cpu_user_used": 85,
"disk_used": 90,
"swap_used": 50,
"memory_used": 95,
"close_wait": 800,
"time_wait": 20000
}'
这个有点儿麻烦。
#!/bin/bash
iplist=list.txt
while read line;do
IP_SEG=$(echo $line | awk -F'.' '{print $3}')
COMMAND_TEMP="jq '.[] |select(.targets[0]|test(\"${line}:9273\"))' ${IP_SEG}.yml | jq '.labels.cpu_user_used="70"'"
eval ${COMMAND_TEMP}
done < "$iplist"
只能将修改结果输出至标准输出,并不能修改源文件。
若要修改源文件,可参考:
https://newbedev.com/modify-a-key-value-in-a-json-using-jq-in-place
curl -s http:\//10.30.151.121:9090/api/v1/query?query=prometheus_target_scrape_pool_targets|jq -c .data.result[].metric.scrape_job
"Prometheus"
"ZF-30.1"
"ZF-30.10"
"ZF-30.11"
"ZF-30.2"
"ZF-30.3"
"ZF-30.4"
"ZF-30.8"
"ZF-30.9"
"ZF-JG-30.7"
"ZF-Redis-30.5"
"ZF-SJZL-30.120"
首先 {}
用于定义一个对象。大部分情况下要有成对的属性及其值,或是函数。像是这样:
var SuperMan = {"Name":"cdmonkey", "AGE":"33"};
上面声明了一个名为 SuperMan 的对象,多个属性或函数用逗号隔开,因为是对象属性。
所以访问时,需要用点号 .
层层进行访问:SuperMan.Name
、SuperMan.AGE
,当然也能够用数组下标方式进行访问:SuperMan["Name"]
、SuperMan["AGE"]
,结果是一样的。
中括号 []
表示一个数组,还可理解为一个数组对象。
参考内容:
https://github.com/stedolan/jq
https://liamlin.me/2019/08/17/jq-tutorial
https://www.ibm.com/developerworks/cn/linux/1612_chengg_jq/index.html
http://einverne.github.io/post/2018/12/jq-command-line-json-processor.html
手册:
大量操作示例: