介紹
jq is like
sed
for JSON data - you can use it to slice and filter and map and transform structured data with the same ease thatsed
,awk
,grep
and friends let you play with text.
jq 可以對 JSON 數(shù)據(jù)進(jìn)行切片、過濾、映射和轉(zhuǎn)換崖媚,和sed
, awk
, grep
命令一樣簡單好用。
jq is written in portable C, and it has zero runtime dependencies. You can download a single binary,
scp
it to a far away machine of the same type, and expect it to work.
jq 是用 C語言編寫的慌植,沒有運(yùn)行時(shí)依賴。獨(dú)立二進(jìn)制文件,可以使用 scp 復(fù)制到其他服務(wù)器直接運(yùn)行。
安裝
Linux
# 下載 https://stedolan.github.io/jq/download/
$ wget https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 -O /usr/local/bin/jq
# 執(zhí)行權(quán)限
$ chmod +x /usr/local/bin/jq
OS X
$ brew install jq
使用
以 njmon 的 json 輸出來演示 jq 的常用方式蛉艾,高級用法見官方手冊。
jq "."
以 json格式化輸出。
$ njmon -s 1 -c 1 | jq '.'
{
"timestamp": {
"datetime": "2020-03-14T19:59:22",
"UTC": "2020-03-14T11:59:22",
"snapshot_seconds": 1,
"snapshot_maxloops": 1,
"snapshot_loop": 0
},
..... 省略其他輸出
}
指定 key 查詢
$ njmon -s 1 -c 1 | jq '.timestamp'
{
"datetime": "2020-03-14T20:14:00",
"UTC": "2020-03-14T12:14:00",
"snapshot_seconds": 1,
"snapshot_maxloops": 1,
"snapshot_loop": 0
}
$ njmon -s 1 -c 1 | jq '.timestamp.datetime'
"2020-03-14T20:14:43"
--raw-output
/-r
標(biāo)準(zhǔn)輸出伺通,即不格式化為帶引號的json 字符串
$ njmon -s 1 -c 1 | jq '.timestamp.datetime'
"2020-03-14T20:14:43"
$ njmon -s 1 -c 1 | jq -r '.timestamp.datetime'
2020-03-14T20:14:43
@csv
:格式化輸出
還有其他格式方式: @html
,@sh
,@base64
,@base64d
等。
$ njmon -s 1 -c 1 | jq -r 'keys' | jq -r '@csv'
"cpu_total","cpuinfo","cpus","disks","filesystems","identity","lscpu","networks","os_release","proc_meminfo","proc_version","proc_vmstat","stat_counters","timestamp","uptime"
數(shù)組
$ njmon -s 1 -c 1 | jq '.cpus'
{
"cpu0": {
"user": 0.999,
"nice": 0,
"sys": 0.999,
"idle": 99.87,
"iowait": 0,
"hardirq": 0,
"softirq": 0,
"steal": 0,
"guest": 0,
"guestnice": 0
},
"cpu1": {
"user": 2.996,
"nice": 0,
"sys": 0.999,
"idle": 97.873,
"iowait": 0,
"hardirq": 0,
"softirq": 0,
"steal": 0,
"guest": 0,
"guestnice": 0
}
}
$ njmon -s 1 -c 1 | jq '.cpus[]'
{
"user": 0.999,
"nice": 0,
"sys": 0.999,
"idle": 99.92,
"iowait": 0,
"hardirq": 0,
"softirq": 0,
"steal": 0,
"guest": 0,
"guestnice": 0
}
{
"user": 2.998,
"nice": 0,
"sys": 0.999,
"idle": 97.922,
"iowait": 0,
"hardirq": 0,
"softirq": 0,
"steal": 0,
"guest": 0,
"guestnice": 0
}
函數(shù)
keys
:獲取JSON中的key信息
$ njmon -s 1 -c 1 | jq 'keys'
[
"cpu_total",
"cpuinfo",
"cpus",
"disks",
"filesystems",
"identity",
"lscpu",
"networks",
"os_release",
"proc_meminfo",
"proc_version",
"proc_vmstat",
"stat_counters",
"timestamp",
"uptime"
]
select(boolean_expression)
:搜索指定條件內(nèi)容
$ njmon -s 1 -c 1 | jq '.filesystems[] | select(.fs_dir == "/home")'
{
"fs_dir": "/home",
"fs_type": "ext4",
"fs_opts": "rw,seclabel,relatime,data=ordered",
"fs_freqs": 0,
"fs_passno": 0,
"fs_bsize": 4096,
"fs_size_mb": 11502,
"fs_free_mb": 11448,
"fs_used_mb": 54,
"fs_full_percent": 0.463,
"fs_avail": 10842,
"fs_files": 757392,
"fs_files_free": 757110,
"fs_namelength": 255
}
has(key)
:判斷是否存在某個(gè)key
$ njmon -s 1 -c 1 | jq 'has("cpus")'
true
$ njmon -s 1 -c 1 | jq 'has("cpus2")'
false
length
:查看輸出長度或個(gè)數(shù)
# 5個(gè)字段
$ njmon -s 1 -c 1 | jq '.timestamp | length'
5
# 長度19
$ njmon -s 1 -c 1 | jq '.timestamp.datetime | length'
19
實(shí)際場景
nacos 工具腳本
在做自動部署腳本時(shí)逢享,需要寫個(gè) Nacos 工具腳本罐监,實(shí)現(xiàn)操作 Nacos 實(shí)例狀態(tài)查看、下線瞒爬、上線等弓柱。針對 Nacos 的 json 結(jié)構(gòu)數(shù)據(jù),使用 jq 來進(jìn)行處理侧但。腳本如下:
nacosUtils.sh
#!/bin/bash
# Nacos工具腳本
# 使用方法
usage() {
echo "Usage: sh $0 {instance|instances|offline|online} URL NAMESPACE_ID SERVICE_NAME IP PORT [FORCE]"
echo "\n"
echo "\t {instance|instances|offline|online} 方法名稱"
echo "\t\t -instance:查詢某個(gè)健康實(shí)例狀態(tài)矢空,true表示在線狀態(tài),false表示下線狀態(tài), 返回空表示實(shí)例不存在"
echo "\t\t -instances:查詢健康實(shí)例總數(shù)"
echo "\t SERVICE_NAME 系統(tǒng)名稱"
echo "\t IP 實(shí)例IP"
echo "\t PORT 實(shí)例啟動端口號"
echo "\t FORCE 方法為offline時(shí)禀横,true表示強(qiáng)制下線屁药,非true表示校驗(yàn)是否多于2個(gè)健康實(shí)例"
echo "\n"
echo "示例:"
echo "\t 啟動:sh $0 instance http://127.0.0.1/nacos ****** serviceName x.x.x.x 8090"
}
# 判斷參數(shù)
if [ $# -lt 4 ];
then
usage
exit 1
fi
# nacos url
URL=$2
# nacos 命名空間
NAMESPACE_ID=$3
# 系統(tǒng)名稱
SERVICE_NAME=$4
# 實(shí)例 IP地址
IP=$5
# 端口
PORT=$6
# 強(qiáng)制下線標(biāo)識
FORCE=$7
# 查看實(shí)例url
instanceListUrl="$URL/v1/ns/catalog/instances?serviceName=$SERVICE_NAME&clusterName=DEFAULT&pageSize=10&pageNo=1&namespaceId=$NAMESPACE_ID"
# 更新實(shí)例
instanceUrl="$URL/v1/ns/instance?serviceName=$SERVICE_NAME&ip=$IP&port=$PORT&namespaceId=$NAMESPACE_ID"
# 查詢健康且上線的實(shí)例個(gè)數(shù)
function instances() {
echo `curl -X GET -s $instanceListUrl | jq -r ".list[] | select(.healthy == true) | select(.enabled == true) | .ip" | wc -l`
}
# 查詢健康實(shí)例狀態(tài) 在線:true;下線:false, 沒有查詢到: 空
function instance() {
echo `curl -X GET -s $instanceListUrl | jq -r ".list[] | select(.ip == \"$IP\") | select(.port == $PORT) | select(.healthy == true) | .enabled"`
}
# 下線 健康實(shí)例總數(shù)為1時(shí)柏锄,不可下線唯一的服務(wù)
function offline() {
if [ "X$FORCE" != "Xtrue" ];then
counts=`instances`
if [ $counts -lt 2 ];then
curl -X GET -s $instanceListUrl | jq .
echo "$SERVICE_NAME 實(shí)例總數(shù)小于2個(gè)酿箭,不可下線唯一的服務(wù)!V和蕖缭嫡!"
exit 1
fi
fi
result=`curl -X PUT -s "$instanceUrl&enabled=false"`
echo $result
}
# 上線
function online() {
enabledFlag=`instance`
if [ "X$enabledFlag" == "Xtrue" ]; then
curl -X GET -s $instanceListUrl | jq .
echo "$SERVICE_NAME 實(shí)例為上線狀態(tài),無需執(zhí)行上線L啤8局!"
else
result=`curl -X PUT -s "$instanceUrl&enabled=true"`
fi
echo $result
}
case "$1" in
'instance')
instance
;;
'instances')
instances
;;
'offline')
offline
;;
'online')
online
;;
*)
usage
exit 1
;;
esac
exit 0
njmon 結(jié)果格式化
njmon與nmon類似笤成,但輸出為 JSON 格式评架,用于服務(wù)器性能統(tǒng)計(jì)。
$ njmon -s 1 -c 1 | jq .
{
"timestamp": {
"datetime": "2020-03-14T19:59:22",
"UTC": "2020-03-14T11:59:22",
"snapshot_seconds": 1,
"snapshot_maxloops": 1,
"snapshot_loop": 0
},
..... 省略其他輸出
}
擴(kuò)展閱讀
- jq 官網(wǎng):https://stedolan.github.io/jq
- jq 在線運(yùn)行:https://jqplay.org/
微信公眾號:daodaotest