[英]Assigning an Array Parsed With jq to Bash Script Array
I parsed a json file with jq like this :我用 jq 解析了一个 json 文件,如下所示:
# cat test.json | jq '.logs' | jq '.[]' | jq '._id' | jq -s
It returns an array like this : [34,235,436,546,.....]
它返回一个这样的数组:
[34,235,436,546,.....]
Using bash script i described an array :使用 bash 脚本我描述了一个数组:
# declare -a msgIds = ...
This array uses ()
instead of []
so when I pass the array given above to this array it won't work.这个数组使用
()
而不是[]
所以当我将上面给出的数组传递给这个数组时它不起作用。
([324,32,45..])
this causes problem. ([324,32,45..])
这会导致问题。 If i remove the jq -s
, an array forms with only 1 member in it.如果我删除
jq -s
,则会形成一个只有 1 个成员的数组。
Is there a way to solve this issue?有没有办法解决这个问题?
We can solve this problem by two ways.我们可以通过两种方式解决这个问题。 They are:
他们是:
Input string:输入字符串:
// test.json
{
"keys": ["key1","key2","key3"]
}
Approach 1:方法一:
1) Use jq -r
(output raw strings, not JSON texts) . 1) 使用
jq -r
(输出原始字符串,而不是 JSON 文本)。
KEYS=$(jq -r '.keys' test.json)
echo $KEYS
# Output: [ "key1", "key2", "key3" ]
2) Use @sh
(Converts input string to a series of space-separated strings). 2) 使用
@sh
(将输入字符串转换为一系列以空格分隔的字符串)。 It removes square brackets[], comma(,) from the string.它从字符串中删除方括号[]、逗号(,)。
KEYS=$(<test.json jq -r '.keys | @sh')
echo $KEYS
# Output: 'key1' 'key2' 'key3'
3) Using tr
to remove single quotes from the string output. 3) 使用
tr
从字符串输出中删除单引号。 To delete specific characters use the -d option in tr
.要删除特定字符,请使用
tr
的 -d 选项。
KEYS=$((<test.json jq -r '.keys | @sh')| tr -d \')
echo $KEYS
# Output: key1 key2 key3
4) We can convert the comma-separated string to the array by placing our string output in a round bracket(). 4)我们可以通过将字符串输出放在圆括号()中来将逗号分隔的字符串转换为数组。 It also called compound Assignment, where we declare the array with a bunch of values.
它也称为复合赋值,我们用一堆值声明数组。
ARRAYNAME=(value1 value2 .... valueN)
#!/bin/bash
KEYS=($((<test.json jq -r '.keys | @sh') | tr -d \'\"))
echo "Array size: " ${#KEYS[@]}
echo "Array elements: "${KEYS[@]}
# Output:
# Array size: 3
# Array elements: key1 key2 key3
Approach 2:方法二:
1) Use jq -r
to get the string output, then use tr
to delete characters like square brackets, double quotes and comma. 1) 使用
jq -r
得到字符串输出,然后使用tr
删除方括号、双引号和逗号等字符。
#!/bin/bash
KEYS=$(jq -r '.keys' test.json | tr -d '[],"')
echo $KEYS
# Output: key1 key2 key3
2) Then we can convert the comma-separated string to the array by placing our string output in a round bracket(). 2)然后我们可以通过将我们的字符串输出放在圆括号()中来将逗号分隔的字符串转换为数组。
#!/bin/bash
KEYS=($(jq -r '.keys' test.json | tr -d '[]," '))
echo "Array size: " ${#KEYS[@]}
echo "Array elements: "${KEYS[@]}
# Output:
# Array size: 3
# Array elements: key1 key2 key3
Use jq -r
to output a string "raw", without JSON formatting, and use the @sh
formatter to format your results as a string for shell consumption.使用
jq -r
输出字符串“raw”,不带 JSON 格式,并使用@sh
格式化程序将结果格式化为字符串以供 shell 使用。 Per the jq docs:根据 jq 文档:
@sh:
@sh:
The input is escaped suitable for use in a command-line for a POSIX shell.
输入已转义,适用于 POSIX shell 的命令行。 If the input is an array, the output will be a series of space-separated strings.
如果输入是数组,则输出将是一系列以空格分隔的字符串。
So can do eg所以可以做例如
msgids=($(<test.json jq -r '.logs[]._id | @sh'))
and get the result you want.并得到你想要的结果。
From the jq FAQ ( https://github.com/stedolan/jq/wiki/FAQ ):从 jq 常见问题解答( https://github.com/stedolan/jq/wiki/FAQ ):
𝑸: How can a stream of JSON texts produced by jq be converted into a bash array of corresponding values? 𝑸:jq 生成的 JSON 文本流如何转换为对应值的 bash 数组?
A: One option would be to use mapfile (aka readarray), for example:答:一种选择是使用 mapfile(又名 readarray),例如:
mapfile -t array <<< $(jq -c '.[]' input.json)
An alternative that might be indicative of what to do in other shells is to use read -r within a while loop.另一种可能指示在其他 shell 中做什么的替代方法是在 while 循环中使用 read -r。 The following bash script populates an array, x, with JSON texts.
以下 bash 脚本使用 JSON 文本填充数组 x。 The key points are the use of the -c option, and the use of the bash idiom
while read -r value; do ... done < <(jq .......)
关键点是 -c 选项的使用,以及
while read -r value; do ... done < <(jq .......)
使用 bash 惯用语while read -r value; do ... done < <(jq .......)
while read -r value; do ... done < <(jq .......)
: while read -r value; do ... done < <(jq .......)
:
#!/bin/bash
x=()
while read -r value
do
x+=("$value")
done < <(jq -c '.[]' input.json)
++ To resolve this, we can use a very simple approach: ++ 为了解决这个问题,我们可以使用一个非常简单的方法:
++ Since I am not aware of you input file, I am creating a file input.json with the following contents: ++ 由于我不知道你的输入文件,我正在创建一个文件 input.json ,内容如下:
input.json:输入.json:
{
"keys": ["key1","key2","key3"]
}
++ Use jq to get the value from the above file input.json: ++ 使用 jq 从上述文件 input.json 中获取值:
Command: cat input.json | jq -r '.keys | @sh'
命令:
cat input.json | jq -r '.keys | @sh'
cat input.json | jq -r '.keys | @sh'
Output: 'key1' 'key2' 'key3'输出:'key1' 'key2' 'key3'
Explanation: |解释: | @sh removes [ and "
@sh 删除 [ 和 "
++ To remove ' ' as well we use tr ++ 为了删除 ' ' 我们也使用 tr
command: cat input.json | jq -r '.keys | @sh' | tr -d \\'
命令:
cat input.json | jq -r '.keys | @sh' | tr -d \\'
cat input.json | jq -r '.keys | @sh' | tr -d \\'
Explanation: use tr delete -d to remove '说明:使用 tr delete -d 删除 '
++ To store this in a bash array we use () with `` and print it: ++ 要将其存储在 bash 数组中,我们使用 () 和 `` 并打印它:
command:命令:
KEYS=(`cat input.json | jq -r '.keys | @sh' | tr -d \'`)
To print all the entries of the array: echo "${KEYS[*]}"
打印数组的所有条目:
echo "${KEYS[*]}"
To correctly parse values that have spaces, newlines (or any other arbitrary characters) just use jq's @sh
filter and bash's declare -a
.要正确解析具有空格、换行符(或任何其他任意字符)的值,只需使用 jq 的
@sh
过滤器和 bash 的declare -a
。
json='{"data":["A B", "C\nD", ""]}'
str=$(jq -r '.data | @sh' <<<"$json")
declare -a arr="($str)" # must be quoted like this
$ declare -p arr
declare -a arr=([0]="A B" [1]=$'C\nD' [2]="")
The reason that this works correctly is that @sh
will produce a space-separated list of shell-quoted words:这正常工作的原因是
@sh
将生成一个空格分隔的 shell 引用单词列表:
$ echo "$str"
'A B' 'C
D' ''
and this is exactly the format that declare
expects for an array definition.这正是
declare
期望数组定义的格式。 No need for a while read
loop or any other pre-processing.不需要
while read
循环或任何其他预处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.