[关闭]
@cdmonkey 2024-06-28T13:58:20.000000Z 字数 4309 阅读 67

jq

命令总结


jq - Command-line JSON processor
  1. jq [options...] filter [files...]

注意:指令只能接受标准 JSON 字符串,输入内容必须严格遵守 JSON 格式标准,属性名必须要使用双引号。

这是一个命令行下的 Json 字符串处置工具,就像 sed 对于文本一样,jq 对应着 Json 文件,这个命令可用不同方案转换 Json 内容。它能够接受文本输入,缺省情况下,它能够从标准输入读入 Json 流。通过同管道进行组合可非常方便的处置 Json。

安装

不用编译安装,直接下载可执行文件就行。

  1. [root@es01 tools]# mv jq-linux64 /usr/local/bin/
  2. [root@es01 tools]# mv /usr/local/bin/jq-linux64 /usr/local/bin/jq
  3. [root@es01 tools]# chmod +x /usr/local/bin/jq
  4. # 其实还可以直接使用 yum 安装:
  5. [root@es01 ~]# yum install -y jq

常用选项:

  1. -c | 紧凑输出,就是输出为一行
  2. -n | 使用 null 作为单个输入值
  3. -e | 根据输出设置退出状态代码
  4. -s | 读入所有输入至数组中,对它进行过滤
  5. -r | 输出原始字符串,而不是 JSON 文本
  6. -R | 读入原始字符串,而不是 JSON 文本
  7. -C | 进行着色
  8. -M | 单色显示,不进行着色
  9. -S | 输出时对键进行排序
  10. --tab | 使用制表符进行缩进

使用

直接处置文件:

  1. # Use this Json file:
  2. [root@es01 ~]# cat input.json
  3. {"name": "cdmonkey", "city": "Beijing"}
  4. ==============
  5. [root@es01 ~]# jq '.' input.json
  6. {
  7. "name": "cdmonkey",
  8. "city": "Beijing"
  9. }

注意:jq 只能接受标准 JSON 内容,输入之文件内容必须要严格遵守 JSON 标准,所有属性名必须是双引号字符串。

格式化 JSON

  1. [root@es01 ~]# echo '{"name": "cdmonkey", "city": "Beijing"}' | jq .
  2. {
  3. "name": "cdmonkey",
  4. "city": "Beijing"
  5. }

将 JSON 文件内容压缩为一行:

  1. [root@es01 ~]# cat target.json
  2. [
  3. {
  4. "targets": ["10.30.8.138:9273"],
  5. "labels": { "alias": "PBS-Zookeeper01" }
  6. },
  7. {
  8. "targets": ["10.30.8.139:9273"],
  9. "labels": { "alias": "PBS-Zookeeper02" }
  10. }
  11. ]
  12. [root@es01 ~]# jq -c . target.json
  13. [{"targets":["10.30.8.138:9273"],"labels":{"alias":"PBS-Zookeeper01"}},{"targets": ...

获得特定文本:

  1. [root@es01 ~]# cat input.json | jq '.name'
  2. "cdmonkey"
  3. # Return null if key does not exist:
  4. [root@es01 ~]# cat input.json | jq '.age'
  5. null

注意:key 的书写支持 .key.key 这样级联访问。

还可使用函数:

  1. [root@es01 ~]# echo "[1,2,3,4]" | jq -rc 'map(.+1)'
  2. [2,3,4,5]
  3. [root@es01 ~]# echo "[1,2,3,4]" | jq -rc 'map(select(.>2))'
  4. [3,4]

轮询

  1. [root@ZF-YW-PROMETHEUS-55aee4 files]# jq '.[]' zf-30-10.yml|jq -r '.targets[0]'
  2. 10.30.10.1:9273
  3. 10.30.10.3:9273
  4. 10.30.10.4:9273
  5. 10.30.10.5:9273
  6. ...

找出所有地址及其对应别名:

  1. jq '.[]' 100.yml|jq -r '.targets[0], .labels.alias'

key=value

  1. [root@elk-fb ~]# echo '{"name": "cdmonkey", "city": "Beijing"}' | \
  2. jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]"
  3. name=cdmonkey
  4. city=Beijing

还能够这样:

  1. [root@elk-fb ~]# cat data.json
  2. {
  3. "SITE_DATA": {
  4. "URL": "suixingpay.com",
  5. "AUTHOR": "cdmonkey",
  6. "CREATED": "2020-09-15"
  7. }
  8. }
  9. jq -r '.SITE_DATA | to_entries | .[] | .key + "=\"" + .value + "\""' data.json
  10. URL="suixingpay.com"
  11. AUTHOR="cdmonkey"
  12. CREATED="2020-09-15"

join

  1. echo '{"name": "cdmonkey", "city": "Beijing"}' | jq -r '[.name,.city]|join(" lives in ")'
  2. cdmonkey lives in Beijing

依据条件查找

就是依据某个属性值查找出相应对象。

https://stackoverflow.com/questions/18592173/select-objects-based-on-value-of-variable-in-object-using-jq

实例:

  1. COMMAND_TEMP="jq '.[]|select(.targets[0]==\"${IP}:9273\")' ${json_file} |jq '.labels.alias'"
  2. ALIAS_TEMP=$(eval ${COMMAND_TEMP})
  3. ALIAS=$(echo ${ALIAS_TEMP}|sed 's/\"//g')
  1. # Then use the test function to compare an attribute to a regex
  2. jq '.[] |select(.labels.alias|test("二维码.*通道"))' zf-30-1.yml|jq '.targets[0]'
  3. # 改造一下:
  4. jq '.[] |select(.labels.alias|test("二维码.*通道")) |.targets[0]' zf-30-10.yml
  1. jq '.[] |select(.labels.application=="QRCODE-AQUERY")' 10.yml
  2. jq '.[] |select(.labels.application=="QRCODE-AQUERY")|.targets[0]' 10.yml

说明:老版本 jq 没有 test 函数,需要 yum 升级至最新版。

  1. jq '.[] |select(.labels.alias|test("商业*")) |.labels.alias, .labels.application' 11.yml
  1. curl -s https://nd.suixingpay.com/api/resources/noToken/resources/monitor/suixingpay/10.30.5|jq -r '.[].targets[0]'

追加内容

  1. jq '.[]' 10.yml |jq --indent 4 '.labels += {
  2. "cpu_load": 200,
  3. "cpu_user_used": 85,
  4. "disk_used": 90,
  5. "swap_used": 50,
  6. "memory_used": 95,
  7. "close_wait": 800,
  8. "time_wait": 20000
  9. }'

修改源文件

这个有点儿麻烦。

  1. #!/bin/bash
  2. iplist=list.txt
  3. while read line;do
  4. IP_SEG=$(echo $line | awk -F'.' '{print $3}')
  5. COMMAND_TEMP="jq '.[] |select(.targets[0]|test(\"${line}:9273\"))' ${IP_SEG}.yml | jq '.labels.cpu_user_used="70"'"
  6. eval ${COMMAND_TEMP}
  7. done < "$iplist"

只能将修改结果输出至标准输出,并不能修改源文件。

若要修改源文件,可参考:

https://newbedev.com/modify-a-key-value-in-a-json-using-jq-in-place


Prometheus

  1. curl -s http:\//10.30.151.121:9090/api/v1/query?query=prometheus_target_scrape_pool_targets|jq -c .data.result[].metric.scrape_job
  2. "Prometheus"
  3. "ZF-30.1"
  4. "ZF-30.10"
  5. "ZF-30.11"
  6. "ZF-30.2"
  7. "ZF-30.3"
  8. "ZF-30.4"
  9. "ZF-30.8"
  10. "ZF-30.9"
  11. "ZF-JG-30.7"
  12. "ZF-Redis-30.5"
  13. "ZF-SJZL-30.120"

Json 基础

首先 {} 用于定义一个对象。大部分情况下要有成对的属性及其值,或是函数。像是这样:

  1. var SuperMan = {"Name":"cdmonkey", "AGE":"33"};

上面声明了一个名为 SuperMan 的对象,多个属性或函数用逗号隔开,因为是对象属性。
所以访问时,需要用点号 . 层层进行访问:SuperMan.NameSuperMan.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

手册:

https://stedolan.github.io/jq/manual

大量操作示例:

http://dwz.date/c47A

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注