Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 当json值包含空格时,将jq输出分配给bash数组_Arrays_Json_Bash_Jq - Fatal编程技术网

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丁格/尾随空格将被删除。