Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.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 如何将bash数组格式化为JSON数组_Arrays_Json_Bash_Jq - Fatal编程技术网

Arrays 如何将bash数组格式化为JSON数组

Arrays 如何将bash数组格式化为JSON数组,arrays,json,bash,jq,Arrays,Json,Bash,Jq,我有一个bash数组 X=("hello world" "goodnight moon") 我想变成一个json数组 ["hello world", "goodnight moon"] 对于我来说,有没有一种好方法可以将其转换为字符串的json数组,而不必在子shell中循环键 (for x in "${X[@]}"; do; echo $x | sed 's|.*|"&"|'; done) | jq -s '.' 这显然行不通 echo "${X[@]}" | jq -s -R

我有一个bash数组

X=("hello world" "goodnight moon")
我想变成一个json数组

["hello world", "goodnight moon"]
对于我来说,有没有一种好方法可以将其转换为字符串的json数组,而不必在子shell中循环键

(for x in "${X[@]}"; do; echo $x | sed 's|.*|"&"|'; done) | jq -s '.'
这显然行不通

echo "${X[@]}" | jq -s -R '.'
您可以使用:

X=("hello world" "goodnight moon")
sed 's/^/[/; s/,$/]/' <(printf '"%s",' "${X[@]}") | jq -s '.'
[
  [
    "hello world",
    "goodnight moon"
  ]
]
X=(“你好世界”“晚安月亮”)
sed的/^/[/;s/,$/]/'此

X=("hello world" "goodnight moon" 'say "boo"' 'foo\bar')

json_array() {
  echo -n '['
  while [ $# -gt 0 ]; do
    x=${1//\\/\\\\}
    echo -n \"${x//\"/\\\"}\"
    [ $# -gt 1 ] && echo -n ', '
    shift
  done
  echo ']'
}

json_array "${X[@]}"
。。。收益率:

["hello world", "goodnight moon", "say \"boo\"", "foo\\bar"]
如果您打算做很多这方面的工作(正如您不愿意使用子shell所表明的那样),那么不依赖任何子流程的此类工作可能对您有利。

您可以这样做:

X=("hello world" "goodnight moon")
printf '%s\n' "${X[@]}" | jq -R . | jq -s .
输出
如果您对一些额外的反斜杠没意见,bash的
printf“%q”
非常有用:

X=("hello world" "goodnight moon" 'say "boo"' 'foo\bar')
json="[$(printf '"%q",' "${X[@]}")"
json="${json%,}]"
echo "$json"

关于反斜杠的OK ness:node.js没有问题:

$ node
> x = ["hello\ world","goodnight\ moon","say\ \"boo\"","foo\\bar"]
[ 'hello world',
  'goodnight moon',
  'say "boo"',
  'foo\\bar' ]

如果值不包含ASCII控制字符(必须在有效JSON中以字符串形式转义),则还可以使用
sed

$X=(“你好世界”“晚安月亮”)
$printf%s\\n“${X[@]}”sed's/[“\]/\\\\&/g;s/*/“&//;1s/^/[;$s/$/]/;$!s/$/,/”
[“你好,世界”,
“晚安月亮”]
如果值包含ASCII控制字符,则可以执行以下操作:

X=($'a\ta'$'a\n\\\”)

对于((i=0;i自jq 1.6以来,您可以这样做:

X=("hello world" "goodnight moon")
printf '%s\n' "${X[@]}" | jq -R . | jq -s .
jq--压缩输出--空输入'$ARGS.positional'--ARGS'${X[@]}
给予:

["hello world","goodnight moon"]

这样做的好处是根本不需要转义。它处理包含换行符、制表符、双引号、反斜杠和其他控制字符的字符串。(嗯,它不处理NUL字符,但首先不能将它们放在bash数组中。)

请注意,不依赖子流程的属性取决于
echo
是否作为shell内置实现,而对于
bash
则是如此。如果是bash,则应使用本机[[和]]而不是[和]。您似乎混淆了,@DennisV.R..
[
是标准实用程序,有时也可以作为shell内置程序使用(请参阅)。bash特有的是
[[[
..
]]
。因此,为了更大的可移植性,我在这个答案中选择前者而不是后者。不过,请注意,这个问题确实特别通过标题、文本和标记指定了
bash
。我想注意这一点[[在bash中,作为本机部件的性能更好,但[正如您所说,作为外部实用程序的兼容性更好。这里可能存在的问题是,如果数组包含控制字符(例如换行符、制表符、表单提要)它不能正确地转义它们,JSON也不允许它们不转义。很好地使用了
printf
,但如果我读到正确的话,那么实际上额外的反斜杠是不正确的。精神上+1和+10:唯一安全和正确的答案。要处理嵌入的换行符,请在“${X[@]}”中使用
for f;执行printf'%s'$f”| jq-R-s.;done | jq-s.
在我的实验中,这将把一个空数组转换为
[“”]
@JanGassen,只有当
X
未声明为数组时才会发生这种情况。
["hello world","goodnight moon"]