BSON数组的JSON列表(不是对象)?

时间:2017-08-31 23:00:20

标签: arrays json linux bash shell

我有一个JSON列表(包含项目列表的键值对的值):

[ "john", "boris", "joe", "frank" ]

我如何将其转换为bash数组,以便迭代它们?

1 个答案:

答案 0 :(得分:2)

简单案例:Newline-Free Strings

简单的方法是使用jq将您的列表转换为每个项目的行,并将其读入您的脚本:

json='[ "john", "boris", "joe", "frank" ]'
readarray -t your_array < <(jq -r '.[]' <<<"$json")
declare -p your_array

......正确发出:

declare -a your_array=([0]="john" [1]="boris" [2]="joe" [3]="frank")

棘手的案例:带有换行符的字符串

有时您需要读取可以包含换行符的字符串(或者希望避免因恶意或格式错误的数据被读入错误字段而导致的安全风险)。为避免这种情况,您可以在数据之间使用NUL分隔符(并删除其中包含的任何NUL值):

json='[ "john\ndoe", "marco\nquent", "malicious\u0000data" ]'

array=( )
while IFS= read -r -d '' item; do
  array+=( "$item" )
done < <(jq -j '.[] | ((. | sub("\u0000"; "<NUL>")) + "\u0000")' <<<"$json")

declare -p array

......正确发出:

declare -a array=([0]=$'john\ndoe' [1]=$'marco\nquent' [2]="malicious<NUL>data")

...和printf '<%s>\n\n' "${array[@]}"正确发出:

<john
doe>

<marco
quent>

<malicious<NUL>data>

(请注意,非常新的bash有readarray -0,这可以避免上面给出的while IFS= read -r -d ''循环的需要,但这还不常见。另请注意,您可以使用该循环直接迭代来自jq的内容,避免首先需要在数组中存储内容;请参阅BashFAQ #1)。