Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.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
在bash数组中存储JQ空分隔输出_Bash_Jq_Nul - Fatal编程技术网

在bash数组中存储JQ空分隔输出

在bash数组中存储JQ空分隔输出,bash,jq,nul,Bash,Jq,Nul,在bash 4.4.12上,使用jq 1.5和这个单行程序IFS=uread-r-a a使用readarray,它获得了一个-d类似于bash4.4中的read上的相同选项: $ readarray -d $'\0' -t a < <(jq -ncj '["a","b","c"][]+"\u0000"') $ declare -p a declare -a a=([0]="a" [1]="b" [2]="c") 这是最好的选择,除非您对数组元素有所了解,从而可以选择一个不属于任何元

在bash 4.4.12上,使用jq 1.5和这个单行程序
IFS=uread-r-a a使用
readarray
,它获得了一个
-d
类似于
bash
4.4中的
read
上的相同选项:

$ readarray -d $'\0' -t a < <(jq -ncj '["a","b","c"][]+"\u0000"')
$ declare -p a
declare -a a=([0]="a" [1]="b" [2]="c")

这是最好的选择,除非您对数组元素有所了解,从而可以选择一个不属于任何元素的备用分隔符。

由于您没有使用jq的
-r
选项,因此出现了一个问题,即标题中提出的问题是否可能是一个错误。如果目标只是将JSON值分配给bash数组,请考虑:

$ readarray -t a < <(jq -nc '["a","b","c"][]') ; printf '%s\n' "${a[@]}"
"a"
"b"
"c"

$readarray-ta<我假设您希望切换到使用空分隔符而不是uu,以提高脚本的可靠性。但是,读取json元素最安全的方法不是使用空分隔符,因为根据RFC7159(),这是允许的json文本。例如,如果
[“a”、“b”、“c”]
看起来像
[“a”、“b\u0000”、“c”]
,并且要将空字符附加到每个字符串并用空分隔符解析这些字符串,“b”元素将进入两个单独的bash数组插槽

相反,如果在使用例如
jq-c
时,换行符总是在json字符串中转义,我建议依赖规范中

“字符串以引号开头和结尾。”

考虑到这一点,我们可以定义:

jsonStripQuotes(){ local t0; while read -r t0; do t0="${t0%\"}"; t0="${t0#\"}"; printf '%s\n' "$t0"; done < <(jq '.');}
…应安全地在单独的行上打印每个json字符串(附加扩展换行符),并转义字符串中的所有换行符和null。之后,我将在IFS设置为仅换行的情况下进行读取:

while IFS=$'\n' do read -r elem; Arr+=("$elem") ; done < <(echo '["a\u0000 b\n","b\nnn","c d"]' | jq .[] | stripJsonQuotes)

我相信这是将json字符串解析为bash数组的最可靠的方法。

readarray
用于将下面的每一行从数组读入一个元素。这里我真正拥有的是一条带有元素的“行”,由\0分隔。我可能是错的,但如果是这样,而且你是对的,
read-a a
readarray
之间有什么区别?
bash
4.4添加了一个
-d
选项,允许你指定一个除
\n
之外的“行”终止符<代码>读取-a
读取一行,并根据
IFS
将其拆分为一个数组
readarray
将多行读取到一个数组中。在
readarray
之前,您必须在读取-d“”项时编写一个类似
的循环;做一个+=(“$item”);完成
以模拟它。(我删除的注释使用了
-d$'\0'
而不是
-d$'\0'
)如果换行符很重要怎么办?例如:
readarray-ta<我的意思是内容的字符没有展开,而是保持转义。我不需要JSON字符串的输出,我需要扩展它。我没有使用-r,因为我使用的是-j。在手册中:>·--join output/-j:>与-r类似,但jq不会在每次输出后打印换行。while循环显然是一种方式,谢谢!我真的希望有一种方法可以实现这一点而不需要循环,但似乎没有任何方法。这通常是您切换到具有适当数据结构和JSON库的语言的时候。
$ readarray -d "" a < <(jq -ncj '["a\\b","\"b\"","c"][]+"\u0000"') ; printf '%s\n' "${a[@]}"
a\b
"b"
c
jsonStripQuotes(){ local t0; while read -r t0; do t0="${t0%\"}"; t0="${t0#\"}"; printf '%s\n' "$t0"; done < <(jq '.');}
echo '["a\u0000 b\n","b\nnn","c d"]' | jq .[] | jsonStripQuotes
while IFS=$'\n' do read -r elem; Arr+=("$elem") ; done < <(echo '["a\u0000 b\n","b\nnn","c d"]' | jq .[] | stripJsonQuotes)
printf '%b' "${Arr[*]}"