将使用jq解析的数组分配给Bash脚本数组

时间:2019-01-08 08:01:56

标签: arrays bash jq

我用jq解析了一个json文件,如下所示:

cat test.json | jq'.logs'| jq'。[]'| jq'._id'| jq -s

它返回这样的数组:[34,235,436,546,.....] 我使用bash脚本描述了一个数组:

声明-a msgIds = ...

此数组使用()而不是[],因此当我将上面给定的数组传递给此数组时,它将不起作用。 ([324,32,45 ..])这会引起问题。如果我删除jq -s,则数组中只有1个成员。 有办法解决这个问题吗?

4 个答案:

答案 0 :(得分:7)

我们可以通过两种方法解决此问题。他们是:

输入字符串:

// test.json
{
    "keys": ["key1","key2","key3"]
}

方法1:

1)使用jq -r(输出原始字符串,而不是JSON文本)。

KEYS=$(jq -r '.keys' test.json)
echo $KEYS
# Output: [ "key1", "key2", "key3" ]

2)使用@sh(将输入字符串转换为一系列以空格分隔的字符串)。它将从字符串中删除方括号[],逗号(,)。

KEYS=$(<test.json jq -r '.keys | @sh')
echo $KEYS
# Output: 'key1' 'key2' 'key3'

3)使用tr从字符串输出中删除单引号。要删除特定字符,请使用tr中的-d选项。

KEYS=$((<test.json jq -r '.keys | @sh')| tr -d \') 
echo $KEYS
# Output: key1 key2 key3

4)通过将字符串输出放在圆括号()中,我们可以将逗号分隔的字符串转换为数组。 它也称为复合赋值,在这里我们用一堆值声明数组。

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

方法2:

1)使用jq -r获取字符串输出,然后使用tr删除方括号,双引号和逗号之类的字符。

#!/bin/bash
KEYS=$(jq -r '.keys' test.json  | tr -d '[],"')
echo $KEYS

# Output: key1 key2 key3

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

答案 1 :(得分:0)

使用jq -r输出字符串“ raw”,而不进行JSON格式化,并使用@sh格式化程序将结果格式化为字符串,以供shell使用。根据jq文档:

  

@sh:

     

对输入进行转义,以适合在POSIX Shell的命令行中使用。如果输入是数组,则输出将是一系列用空格分隔的字符串。

例如,可以做到

msgids=($(<test.json jq -r '.logs[]._id | @sh'))

并获得所需的结果。

答案 2 :(得分:0)

通过jq常见问题解答(https://github.com/stedolan/jq/wiki/FAQ):

:如何将jq生成的JSON文本流转换为对应值的bash数组?

A:一种选择是使用mapfile(又名readarray),例如:

mapfile -t array <<< $(jq -c '.[]' input.json)

一种可能表明在其他shell中做什么的替代方法是在while循环中使用read -r。以下bash脚本使用JSON文本填充数组x。关键点是使用-c选项以及使用bash惯用语while read -r value; do ... done < <(jq .......)

#!/bin/bash
x=()
while read -r value
do
  x+=("$value")
done < <(jq -c '.[]' input.json)

答案 3 :(得分:0)

++ 为了解决这个问题,我们可以使用一个非常简单的方法:

++ 由于我不知道你的输入文件,我正在创建一个包含以下内容的文件 input.json:

input.json:

{
    "keys": ["key1","key2","key3"]
}

++ 使用jq从上面的文件input.json中获取值:

命令:cat input.json | jq -r '.keys | @sh'

输出:'key1' 'key2' 'key3'

解释: | @sh 删除 [ 和 "

++ 为了删除“ ”,我们使用 tr

命令:cat input.json | jq -r '.keys | @sh' | tr -d \'

说明:使用tr delete -d删除'

++ 要将其存储在 bash 数组中,我们使用 () 和 `` 并打印它:

命令:

KEYS=(`cat input.json | jq -r '.keys | @sh' | tr -d \'`)

打印数组的所有条目:echo "${KEYS[*]}"