简单的方法是将jq
列表转换为每项一行,并将其读入脚本中:
json='[ "john", "boris", "joe", "frank" ]'
readarray -t your_array < <(jq -r '.[]' <<<"$json")
declare -p your_array
Run Code Online (Sandbox Code Playgroud)
...正确发出:
declare -a your_array=([0]="john" [1]="boris" [2]="joe" [3]="frank")
Run Code Online (Sandbox Code Playgroud)
有时您需要读取可能包含换行符的字符串(或者希望避免由于恶意或格式错误的数据被读入错误字段而导致的安全风险)。为了避免这种情况,您可以在数据之间使用 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
Run Code Online (Sandbox Code Playgroud)
...正确发出:
declare -a array=([0]=$'john\ndoe' [1]=$'marco\nquent' [2]="malicious<NUL>data")
Run Code Online (Sandbox Code Playgroud)
...并printf '<%s>\n\n' "${array[@]}"
正确发出:
<john
doe>
<marco
quent>
<malicious<NUL>data>
Run Code Online (Sandbox Code Playgroud)
(请注意,非常新的 bash 有readarray -0
,它可以避免上面给出的循环的需要while IFS= read -r -d ''
,但这还不常见。另请注意,您可以使用该循环直接迭代 中的内容jq
,从而避免需要将内容存储在数组中第一名;请参阅BashFAQ #1)。