jq学习
一、jq 簡介
JSON 是一種輕量級且與語言無關(guān)的數(shù)據(jù)存儲格式,易于與大多數(shù)編程語言集成,也易于理解 。雖然它以 JavaScript 開頭,而且主要用于在服務(wù)器和瀏覽器之間交換數(shù)據(jù),但現(xiàn)在正在用于許多領(lǐng)域,包括嵌入式系統(tǒng)。JSON是前端編程經(jīng)常用的格式,對于PHP或Python,解析JSON很容易,尤其是PHP的json_encode和json_decode。Linux下處理JSON的神器是jq。對于JSON格式而言,jq就像sed/awk/grep這些神器一樣的方便,jq沒有亂七八糟的依賴,只需要一個binary文件jq就可以了。Linux 上使用命令行工具jq來解析并格式化打印 JSON,它對于在 shell 腳本中處理大型 JSON 數(shù)據(jù)或在 shell 腳本中處理 JSON 數(shù)據(jù)非常有用。
JSON 是一種輕量級的數(shù)據(jù)交換格式,其采用完全獨立于語言的文本格式,具有方便人閱讀和編寫,同時也易于機器的解析和生成。這些特性決定了 JSON 格式越來越廣泛的應(yīng)用于現(xiàn)代的各種系統(tǒng)中。作為系統(tǒng)管理員,在日常的工作中無論是編輯配置文件或者通過 http 請求查詢信息,我們都不可避免的要處理 JSON 格式的數(shù)據(jù)。
jq 是一款命令行下處理 JSON 數(shù)據(jù)的工具,其可以接受標準輸入,命令管道或者文件中的 JSON 數(shù)據(jù),經(jīng)過一系列的過濾器 (filters)?和表達式的轉(zhuǎn)后形成我們需要的數(shù)據(jù)結(jié)構(gòu)并將結(jié)果輸出到標準輸出中。jq 的這種特性使我們可以很容易地在 Shell 腳本中調(diào)用它。
二、jq 安裝
在這個地址下載源碼包https://stedolan.github.io/jq/download/?
?tar zxf jq-1.5.tar.gz
./configure && make && sudo make install
完成安裝
三、jq使用
1、創(chuàng)建
[root@idc-dhcp01 ~]# jq -n {a:1} {"a": 1 } [root@idc-dhcp01 ~]# jq -n '{a:"test"}' {"a": "test" }2、合并
[root@idc-dhcp01 ~]# jq -n '{a:"test" } + {b:4}' {"a": "test","b": 4 } [root@idc-dhcp01 ~]# jq -n '{a:"test"} + {b:2} + {c:"testc"}' {"a": "test","b": 2,"c": "testc" }3、刪除
[root@idc-dhcp01 ~]# cat test.json {"a":1,"b":"test","c":"hello"}[root@idc-dhcp01 ~]# cat test.json | jq . {"a": 1,"b": "test","c": "hello" } [root@idc-dhcp01 ~]# cat test.json | jq 'del(.b)' {"a": 1,"c": "hello" }4、更新
[root@idc-dhcp01 ~]# cat test.json {"a":1,"b":"test","c":"hello"} [root@idc-dhcp01 ~]# cat test.json | jq '(.b="world")' {"a": 1,"b": "world","c": "hello" }[root@idc-dhcp01 ~]# cat test.json | jq '. + {d:"python"}' {"a": 1,"b": "test","c": "hello","d": "python" }[root@idc-dhcp01 ~]# cat test.json | jq '.d={dd:5}' {"a": 1,"b": "test","c": "hello","d": {"dd": 5} }5、查詢
[root@idc-dhcp01 ~]# cat test.json | jq . {"a": 1,"b": "test","c": "hello" }[root@idc-dhcp01 ~]# cat test.json | jq '. + {d:4}' | jq '.d={dd:5}' | jq .d.dd 5 [root@idc-dhcp01 ~]# cat test.json | jq '. + {d:4}' | jq '.d={dd:5}' | jq .a 1 [root@idc-dhcp01 ~]# echo '{"a":1,"b":2}' | jq '[.a,.b]' [1,2 ]6、查看數(shù)據(jù)類型
[root@idc-dhcp01 ~]# echo {} | jq -r type object[root@idc-dhcp01 ~]# echo '[0, false, [], {}, null, "hello"]' |jq 'map(type)' ["number","boolean","array","object","null","string" ]7、查詢數(shù)組中的值
[root@idc-dhcp01 ~]# echo [1,2,3] | jq .[1] 2 [root@idc-dhcp01 ~]# echo [1,2,3] | jq .[2] 38、查詢數(shù)組長度
[root@idc-dhcp01 ~]# echo [1,2,3] | jq '.|length' 3 [root@idc-dhcp01 ~]# echo [1,2,3,5,6] | jq '.|length' 59、數(shù)組相加
[root@idc-dhcp01 ~]# echo [1,2,3] | jq '. +[4,5,6]' [1,2,3,4,5,6 ]10、高級查詢
[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"11、類型轉(zhuǎn)換
?
四、應(yīng)用
監(jiān)控服務(wù)器硬件信息
[root@sys-idc-pxe01 ~]# cat ./get_server_info.sh #!/bin/sh #description: get server hardware info #author: liuxin #date: 20180122 #需要安裝jq工具 yum install jq#用于存放該服務(wù)器的所有信息,個人喜歡把全局變量寫到外面 #寫到函數(shù)里面,沒有加local的變量也是全局變量 INFO="{}"#定義一個工具函數(shù),用于生成json數(shù)值,后面將會頻繁用到 function create_json() {#utility functionlocal key=$1local value="$2"local json=""#if value is stringif [ -z "$(echo "$value" |egrep "\[|\]|\{|\}")" ]thenjson=$(jq -n {"$key":"\"$value\""})#if value is json, objectelif [ "$(echo "$value" |jq -r type)" == "object" ]thenjson=$(jq -n {"$key":"$value"})#if value is arrayelif [ "$(echo "$value" |jq -r type)" == "array" ]thenjson=$(jq -n "{$key:$value}")elseecho "value type error..."exit 1return 0fiecho $jsonreturn 0 }#獲取CPU信息 function get_cpu() {#獲取cpu信息,去掉空格和制表符和空行,以便于for循環(huán)local cpu_model_1=$(dmidecode -s processor-version |grep '@' |tr -d " " |tr -s "\n" |tr -d "\t")local cpu_info="{}"local i=0#因為去掉了空格和制表符,以下默認使用換行符分隔for line in $(echo "$cpu_model_1")dolocal cpu_model="$line"local cpu1=$(create_json "cpu_model" "$cpu_model")#獲取每塊cpu的信息,這里只記錄了型號local cpu=$(create_json "cpu_$i" "$cpu1")local cpu_info=$(jq -n "$cpu_info + $cpu")i=$[ $i + 1]done#將cpu的信息整合成一個json,key是cpulocal info=$(create_json "cpu" "$cpu_info")#將信息加入到全局變量中INFO=$(jq -n "$INFO + $info")return 0 }function get_mem() {#generate json {Locator:{sn:sn,size:size}}local mem_info="{}"#獲取每個內(nèi)存的信息,包括Size:|Locator:|Serial Number:local mem_info_1=$(dmidecode -t memory |egrep 'Size:|Locator:|Serial Number:' |grep -v 'Bank Locator:' |awk '{if (NR%3==1 && $NF=="MB"){size=$2;getline (NR+1);locator=$2;getline (NR+2);sn=$NF;printf("%s,%s,%s\n",locator,size,sn)}}')#根據(jù)上面的信息,將信息過濾并整合成jsonlocal i=0for line in $(echo "$mem_info_1")dolocal locator=$(echo $line |awk -F , '{print $1}')local sn=$(echo $line |awk -F , '{print $3}')local size=$(echo $line |awk -F , '{print $2}')local mem1=$(create_json "locator" "$locator")local mem2=$(create_json "sn" "$sn")local mem3=$(create_json "size" "$size")local mem4=$(jq -n "$mem1 + $mem2 + $mem3")#每條內(nèi)存的信息,key是內(nèi)存從0開始的序號local mem=$(create_json "mem_$i" "$mem4")#將這些內(nèi)存的信息組合到一個json中mem_info=$(jq -n "$mem_info + $mem")i=$[ $i + 1 ]done#給這些內(nèi)存的信息設(shè)置key,memlocal info=$(create_json "mem" "$mem_info")INFO=$(jq -n "$INFO + $info")return 0 }function get_megacli_disk() {#設(shè)置megacli工具的路徑,此條可以根據(jù)情況更改local raid_tool="/opt/MegaRAID/MegaCli/MegaCli64"#將硬盤信息獲取,保存下來,省去每次都執(zhí)行的操作$raid_tool pdlist aall >/tmp/megacli_pdlist.txtlocal disk_info="{}"#獲取硬盤的必要信息local disk_info_1=$(cat /tmp/megacli_pdlist.txt |egrep 'Enclosure Device ID:|Slot Number:|PD Type:|Raw Size:|Inquiry Data:|Media Type:'|awk ' {if(NR%6==1 && $1$2=="EnclosureDevice"){E=$NF;getline (NR+1);S=$NF;getline (NR+2);pdtype=$NF;getline (NR+3);size=$3$4;getline (NR+4);sn=$3$4$5$6;getline (NR+5);mediatype=$3$4$5$6;printf("%s,%s,%s,%s,%s,%s\n",E,S,pdtype,size,sn,mediatype)} }')#將獲取到的硬盤信息進行整合,生成jsonlocal i=0for line in $(echo $disk_info_1)do#local key=$(echo $line |awk -F , '{printf("ES%s_%s\n",$1,$2)}')local E=$(echo $line |awk -F , '{print $1}')local S=$(echo $line |awk -F , '{print $2}')local pdtype=$(echo $line |awk -F , '{print $3}')local size=$(echo $line |awk -F , '{print $4}')local sn=$(echo $line |awk -F , '{print $5}')local mediatype=$(echo $line |awk -F , '{print $6}')local disk1=$(create_json "pdtype" "$pdtype")local disk1_1=$(create_json "enclosure_id" "$E")local disk1_2=$(create_json "slot_id" "$S")local disk2=$(create_json "size" "$size")local disk3=$(create_json "sn" "$sn")local disk4=$(create_json "mediatype" "$mediatype")local disk5=$(jq -n "$disk1 + $disk1_1 + $disk1_2 + $disk2 + $disk3 + $disk4")local disk=$(create_json "disk_$i" "$disk5")disk_info=$(jq -n "$disk_info + $disk")i=$[ $i + 1 ]done#echo $disk_infolocal info=$(create_json "disk" "$disk_info")INFO=$(jq -n "$INFO + $info")return 0 }function get_hba_disk() {#對于hba卡的硬盤,使用smartctl獲取硬盤信息local disk_tool="smartctl"local disk_info="{}"#lsscsi 需要使用yum install lsscsi 安裝local disk_info_1=$(lsscsi -g |grep -v 'enclosu' |awk '{printf("%s,%s,%s,%s\n",$1,$2,$(NF-1),$NF)}')local i=0for line in $(echo $disk_info_1)dolocal E=$(echo $line |awk -F , '{print $1}' |awk -F ':' '{print $1}' |tr -d '\[|\]')local S=$(echo $line |awk -F , '{print $NF}' |egrep -o [0-9]*)local sd=$(echo $line |awk -F , '{print $(NF-1)}')$disk_tool -i $sd >/tmp/disk_info.txtlocal pdtype="SATA"if [ "$(cat /tmp/disk_info.txt |grep 'Transport protocol:' |awk '{print $NF}')" == "SAS" ]thenlocal pdtype="SAS"filocal size=$(cat /tmp/disk_info.txt |grep 'User Capacity:' |awk '{printf("%s%s\n",$(NF-1),$NF)}' |tr -d '\[|\]')local sn=$(cat /tmp/disk_info.txt |grep 'Serial Number:' |awk '{print $NF}')local mediatype="disk"local disk1=$(create_json "pdtype" "$pdtype")local disk1_1=$(create_json "enclosure_id" "$E")local disk1_2=$(create_json "slot_id" "$S")local disk2=$(create_json "size" "$size")local disk3=$(create_json "sn" "$sn")local disk4=$(create_json "mediatype" "$mediatype")local disk5=$(jq -n "$disk1 + $disk1_1 + $disk1_2 + $disk2 + $disk3 + $disk4")local disk=$(create_json "disk_$i" "$disk5")disk_info=$(jq -n "$disk_info + $disk")i=$[ $i + 1 ]done#echo $disk_infolocal info=$(create_json "disk" "$disk_info")INFO=$(jq -n "$INFO + $info")return 0 }function get_disk() {#根據(jù)獲取到的硬盤控制器類型,來判斷使用什么工具采集硬盤信息if [ "$(echo "$INFO" |jq -r .disk_ctrl.disk_ctrl_0.type)" == "raid" ]thenget_megacli_diskelif [ "$(echo "$INFO" |jq -r .disk_ctrl.disk_ctrl_0.type)" == "hba" ]thenget_hba_diskelselocal info=$(create_json "disk" "error")INFO=$(jq -n "$INFO + $info")fi#hp機器比較特殊,這里我沒有做hp機器硬盤信息采集,有興趣的朋友可以自行添加上#if hp machinereturn 0 }function get_diskController() {local disk_ctrl="{}"#if LSI Controllerlocal disk_ctrl_1="$(lspci -nn |grep LSI)"local i=0#以換行符分隔IFS_OLD=$IFS && IFS=$'\n'for line in $(echo "$disk_ctrl_1")do#echo $linelocal ctrl_id=$(echo "$line" |awk -F ']:' '{print $1}' |awk '{print $NF}' |tr -d '\[|\]')case "$ctrl_id" in#根據(jù)控制器的id或進行判斷是raid卡還是hba卡,因為品牌比較多,后續(xù)可以在此處進行擴展添加0104)# 獲取Logic以后的字符串,并進行拼接local ctrl_name=$(echo "${line##*"Logic"}" |awk '{printf("%s_%s_%s\n",$1,$2,$3)}')local ctrl1=$(create_json "id" "$ctrl_id")local ctrl2=$(create_json "type" "raid")local ctrl3=$(create_json "name" "$ctrl_name");;0100|0107)local ctrl_name=$(echo "${line##*"Logic"}" |awk '{printf("%s_%s_%s\n",$1,$3,$4)}')local ctrl1=$(create_json "id" "$ctrl_id")local ctrl2=$(create_json "type" "hba")local ctrl3=$(create_json "name" "$ctrl_name");;*)local ctrl1=$(create_json "id" "----")local ctrl2=$(create_json "type" "----")local ctrl3=$(create_json "name" "----");;esaclocal ctrl_tmp=$(jq -n "$ctrl1 + $ctrl2 + $ctrl3")local ctrl=$(create_json "disk_ctrl_$i" "$ctrl_tmp")disk_ctrl=$(jq -n "$disk_ctrl + $ctrl")i=$[ $i + 1 ]doneIFS=$IFS_OLDlocal info=$(create_json "disk_ctrl" "$disk_ctrl")INFO=$(jq -n "$INFO + $info")return 0 }function get_netcard() {local netcard_info="{}"local netcard_info_1="$(lspci -nn |grep Ether)"local i=0#echo "$netcard_info_1"IFS_OLD=$IFS && IFS=$'\n'for line in $(echo "$netcard_info_1")dolocal net_id=$(echo $line |egrep -o '[0-9a-z]{4}:[0-9a-z]{4}')local net_id_1=$(echo $net_id |awk -F : '{print $1}')case "$net_id_1" in8086)local net_name=$(echo "${line##*": "}" |awk '{printf("%s_%s_%s_%s\n",$1,$3,$4,$5)}')local type=$(echo $line |egrep -o SFP || echo "TP")local net1=$(create_json "id" "$net_id")local net2=$(create_json "name" "$net_name")local net3=$(create_json "type" "$type");;14e4)local net_name=$(echo "${line##*": "}" |awk '{printf("%s_%s_%s_%s\n",$1,$3,$4,$5)}')local type=$(echo $line |egrep -o SFP || echo "TP")local net1=$(create_json "id" "$net_id")local net2=$(create_json "name" "$net_name")local net3=$(create_json "type" "$type");;*)local net_name=$(echo "${line##*": "}" |awk '{printf("%s_%s_%s_%s\n",$1,$3,$4,$5)}')local type=$(echo $line |egrep -o SFP || echo "TP")local net1=$(create_json "id" "$net_id")local net2=$(create_json "name" "$net_name")local net3=$(create_json "type" "$type");;esaclocal net1=$(jq -n "$net1 + $net2 + $net3")#echo $netlocal net2=$(create_json "net_$i" "$net1")netcard_info=$(jq -n "$netcard_info + $net2")i=$[ $i + 1 ]doneIFS=$IFS_OLDlocal info=$(create_json "net" "$netcard_info")INFO=$(jq -n "$INFO + $info")return 0 }function get_server() {local product=$(dmidecode -s system-product-name |grep -v '^#' |tr -d ' ' |head -n1)local manufacturer=$(dmidecode -s system-manufacturer |grep -v '^#' |tr -d ' ' |head -n1)local server1=$(create_json "manufacturer" "$manufacturer")local server2=$(create_json "product" "$product")local server3=$(jq -n "$server1 + $server2")local info=$(create_json "basic_info" "$server3")INFO=$(jq -n "$INFO + $info")return 0 }ALL_INFO="" function get_all() {#因為硬盤信息的獲取依賴硬盤控制器的信息,所以get_diskController要放到get_disk前面get_serverget_cpuget_memget_diskControllerget_diskget_netcardlocal sn=$(dmidecode -s system-serial-number |grep -v '^#' |tr -d ' ' |head -n1)#ALL_INFO=$(create_json "$sn" "$INFO")return 0 }function main() {get_all# echo $ALL_INFOecho $INFOreturn 0 }#------------------------------------------------- main參考文檔:https://www.cnblogs.com/kevingrace/p/7565371.html
?
總結(jié)
- 上一篇: 分布式系统架构之IDC机房
- 下一篇: KITTI数据集学习笔记