Arrays 当json值包含空格时,将jq输出分配给bash数组
当我这样做时:Arrays 当json值包含空格时,将jq输出分配给bash数组,arrays,json,bash,jq,Arrays,Json,Bash,Jq,当我这样做时: arr=($(echo '{"crew":[{"name":"kirk"},{"name":"bones"},{"name":"mr spock"}]}' | jq -r '.crew[].name | @sh')) arr=("kirk" "bones" "mr spock")
arr=($(echo '{"crew":[{"name":"kirk"},{"name":"bones"},{"name":"mr spock"}]}' | jq -r '.crew[].name | @sh'))
arr=("kirk" "bones" "mr spock")
我得到:
echo "${arr[2]}"
mr
echo "${arr[3]}"
spock
但是,当我这样做时:
arr=($(echo '{"crew":[{"name":"kirk"},{"name":"bones"},{"name":"mr spock"}]}' | jq -r '.crew[].name | @sh'))
arr=("kirk" "bones" "mr spock")
我明白了:
echo "${arr[2]}"
mr spock
在第一个示例中,为什么bash在创建数组时会忽略每个jq值所包含的引号?$ari=($(echo'{“crew”:[{“name”:“kirk”},{“name”:“bones”},{“name”:“mr spock”}}}'|jq-r'.crew[].name |@sh'))
$declare-p元
declare-a ary=([0]=“kirk'”[1]=“bones'”[2]=“mr”[3]=“spock'”)
这并不像预期的那样工作,因为命令替换是不带引号的,bash将对输出执行单词拆分。实际输出是否包含引号字符并不重要。请参阅本手册中的
您需要延迟数组分配,直到shell可以检查输出的内容。这可以通过eval
完成,但对于变量赋值,最好通过declare
完成:
$declare-a“ary=($(echo'{“crew”:[{“name”:“kirk”},{“name”:“bones”},{“name”:“mr spock”}}}}'| jq-r'.crew[].name |@sh'))
$declare-p元
declare-a ary=([0]=“kirk”[1]=“bones”[2]=“spock先生”)
为了便于阅读,请将其分为以下步骤:
$jq_out=$(echo'{“crew”:[{“name”:“kirk”},{“name”:“bones”},{“name”:“mr spock”}}}},{“mr spock”}]}jq-r.crew[].name |@sh')
$declare-a“ary=($jq_out)”
$declare-p元
declare-a ary=([0]=“kirk”[1]=“bones”[2]=“spock先生”)
如果您的bash不支持mapfile/readarray,您可以使用以下说明的习惯用法:
echo $BASH_VERSION
while read -r name ; do
ary+=("$name")
done < <(echo '{"crew":[{"name":"kirk"},{"name":"bones"},{"name":"mr spock"}]}' |
jq -r '.crew[].name')
declare -p ary
特别注意
在数组更新行中被引用$name
- 没有必要使用
,在这种情况下,这可能不是您想要的@sh
当然,如果JSON字符串可能包含嵌入的新行,则必须相应地调整上述内容,例如使用NUL(
“\u0000”
)作为分隔符。您使用jq去掉了引号-r@RamanSailopal根据jq手册,jq操作员@sh
将退出输出:“输入转义适合在POSIX shell的命令行中使用。如果输入是一个数组,则输出将是一系列空格分隔的字符串。“你能不能…readarray-t arr@RamanSailopal是的,readarray
似乎可以工作。谢谢。但是,我仍然有兴趣知道为什么bash似乎删除/忽略jq包装值的引号。@JonHudson请参阅(这是一种不同的情况,但分词过程完全相同)。谢谢,这有助于我理解为什么会发生这种情况。我不知道删除引号是一件事,但为了简单起见,因为我更了解它,我将使用上面的readarray
解决方案。您将需要使用IFS=read-r name
——它将一字不差地读取该行。如果没有IFS=
,则lea丁格/尾随空格将被删除。