JSON是前端编程经常用到的格式,对于PHP或者Python,解析JSON都不是什么大事,尤其是PHP的json_encode和json_decode,干的相当的漂亮。Linux下也有处理处理JSON的神器:jq。 对于JSON格式而言,jq就像sed/awk/grep这些神器一样的方便,而也,jq没有乱七八糟的依赖,只需要一个binary文件jq,就足矣。下面我们看下jq的使用。 1. 安装 官网:https://stedolan.github.io/jq/download/ Linux jq 1.5…
Shell:jq 循环 json 对象, jq 循环 json 数组, jq 用法实践, jq converts a JSON object to key=value, jq parses one field from an JSON array into bash array
1. 转换数字为字符串 How do I use jq to convert number to string?
Given the following jq command and Json:
jq '.[]|[.string,.number]|join(": ")' <<< '
[
{
"number": 3,
"string": "threee"
},
{
"number": 7,
"string": "seven"
}
]
'
I’m trying to format the output as:
three: 3 seven: 7
方法:The jq command has the tostring function. It took me a while to learn to use it by trial and error. Here is how to use it:
jq -r '.[] | [ .string, .number|tostring ] | join(": ")' <<< '
[{ "number": 9, "string": "nine"},
{ "number": 4, "string": "four"}]
'
#nine: 9
#four: 4
2. 转换 json 对象为 key=value 形式,How to convert a JSON object to key=value format in jq?
In jq, how can I convert a JSON to a string with key=value?
From:
{
"var": 1,
"foo": "bar",
"x": "test"
}
To:
var=1 foo=bar x=test
方法:You could try:
jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" test.json
Here’s a demo:
$ cat test.json
{
"var": 1,
"foo": "bar",
"x": "test"
}
$ jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" test.json
#foo=bar
#var=1
#x=test
或者可以使用:
$ cat data.json
{
"SITE_DATA": {
"URL": "example.com",
"AUTHOR": "John Doe",
"CREATED": "10/22/2017"
}
}
You can make a much simpler version of the jq program:
jq -r '.SITE_DATA | to_entries | .[] | .key + "=\"" + .value + "\""'
which outputs:
URL="example.com" AUTHOR="John Doe" CREATED="10/22/2017"
This string is evalable as long as the characters `, $, newline and null don’t appear in the data:
eval "$(jq -r '.SITE_DATA | to_entries | .[] | .key + "=\"" + .value + "\""' < data.json)" echo "$AUTHOR"
或者:
Just realized that I can loop over the results and eval each iteration:
constants=$(cat ${1} | jq '.SITE_DATA' | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]")
for key in ${constants}; do
eval ${key}
done
Allows me to do:
echo ${AUTHOR}
# outputs John Doe
3. 将输出化为一行 Get outputs from jq on a single line
-c is what you likely need
Using the output you posted above, you can process it further:
jq -c . input
To Give;
{"key":"SEA-739","status":"Open","assignee":null}
{"key":"SEA-738","status":"Resolved","assignee":"user2@mycompany.com"}
Or you can just change your original command
FROM
jq -r '(.issues[] | {key, status: .fields.status.name, assignee: .fields.assignee.emailAddress})'
TO
jq -c '(.issues[] | {key, status: .fields.status.name, assignee: .fields.assignee.emailAddress})'
4. json 数组转 bash 数组 parse one field from an JSON array into bash array
I have a JSON output that contains a list of objects stored in a variable. (I may not be phrasing that right)
[
{
"item1": "value1",
"item2": "value2",
"sub items": [
{
"subitem": "subvalue"
}
]
},
{
"item1": "value1_2",
"item2": "value2_2",
"sub items_2": [
{
"subitem_2": "subvalue_2"
}
]
}
]
Using jq :
$ cat json
[
{
"item1": "value1",
"item2": "value2",
"sub items": [
{
"subitem": "subvalue"
}
]
},
{
"item1": "value1_2",
"item2": "value2_2",
"sub items_2": [
{
"subitem_2": "subvalue_2"
}
]
}
]
CODE:
arr=( $(jq -r '.[].item2' json) )
printf '%s\n' "${arr[@]}"
OUTPUT:
value2 value2_2
5. jq 遍历 json 数组,遍历 json 对象,Bash for Loop Over JSON Array Using jq
First we will start with some data:
sample='[{"name":"foo"},{"name":"bar"}]'
echo "${sample}" | jq '.'
输出
[
{
"name": "foo"
},
{
"name": "bar"
}
]
By using jq --compact-output (or -c) we can get each object on a newline.
sample='[{"name":"foo"},{"name":"bar"}]'
echo "${sample}" | jq -c '.[]'
输出
{"name":"foo"}
{"name":"bar"}
We could start iterating of the above with a Bash for loop if our data does not contain spaces or newlines. But since certificates contain newlines we better base64 encode each line. Also, instead of -c, we now use -r to get rid of the extra quotes.
sample='[{"name":"foo"},{"name":"bar"}]'
echo "${sample}" | jq -r '.[] | @base64'
输出
eyJuYW1lIjoiZm9vIn0= eyJuYW1lIjoiYmFyIn0=
Now let’s build our for loop.
sample='[{"name":"foo"},{"name":"bar"}]'
for row in $(echo "${sample}" | jq -r '.[] | @base64'); do
_jq() {
echo ${row} | base64 --decode | jq -r ${1}
}
echo $(_jq '.name')
done
输出
foo bar
实例:
cat test.json | jq -c -r ".[] | {status : .status}" | while read row
do
_jq() {
echo ${row} | jq -r ${1}
}
echo $(_jq '.status')
done
以上代码等同于:
cat test.json | jq -r ".[] | {status: .status} | @base64" | while read row
do
_jq() {
echo ${row} | base64 --decode | jq -r ${1}
}
echo $(_jq '.status')
done
6. 解决报错:parse error: Invalid string: control characters from U+0000 through U+001F must be escaped at line 3, column 9 或者 jq: error (at :1): Cannot index string with string “expand”
Newlines not supported on jqplay with jq 1.5. They must be escaped as \n or as \u000a.
一般原因是因为 jq 1.5的版本不知道 json 换行,解决方法如下:
json_string=$(echo ${string} | tr '\r\n' ' ')
#或者采用直接删除的方式
json_string=$(echo ${string} | tr -d '\r\n')
通过 tr 函数做一个替换即可!
7. jq 在线测试网站:
在线测试:https://jqplay.org/

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















![]()


