我有一个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 '.'
答案 0 :(得分:13)
你可以这样做:
X=("hello world" "goodnight moon")
printf '%s\n' "${X[@]}" | jq -R . | jq -s .
[
"hello world",
"goodnight moon"
]
答案 1 :(得分:3)
这......
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建议)那么这样的东西不依赖于任何子进程可能对你有利。
答案 2 :(得分:3)
从 jq 1.6 开始,您可以这样做:
jq --compact-output --null-input '$ARGS.positional' --args "${X[@]}"
给予:
["hello world","goodnight moon"]
这样做的好处是根本不需要转义。它处理包含换行符、制表符、双引号、反斜杠和其他控制字符的字符串。 (好吧,它不处理 NUL 字符,但首先你不能将它们放在 bash 数组中。)
答案 3 :(得分:0)
您可以使用:
X=("hello world" "goodnight moon")
sed 's/^/[/; s/,$/]/' <(printf '"%s",' "${X[@]}") | jq -s '.'
[
[
"hello world",
"goodnight moon"
]
]
答案 4 :(得分:0)
如果值不包含ASCII控制字符(必须在有效JSON中的字符串中进行转义),您还可以使用sed
:
$ X=("hello world" "goodnight moon")
$ printf %s\\n "${X[@]}"|sed 's/["\]/\\&/g;s/.*/"&"/;1s/^/[/;$s/$/]/;$!s/$/,/'
["hello world",
"goodnight moon"]
如果值包含ASCII控制字符,您可以执行以下操作:
X=($'a\ta' $'a\n\\\"')
for((i=0;i<${#X[@]};i++));do
[ $i = 0 ]&&printf \[
printf \"
e=${X[i]}
e=${e//\\/\\\\}
e=${e//\"/\\\"}
for((j=0;j<${#e};j++));do
c=${e:j:1}
if [[ $c = [[:cntrl:]] ]];then
printf '\\u%04x' "'$c"
else
printf %s "$c"
fi
done
printf \"
if((i<=${#X[@]}-2));then
printf ,
else
printf \]
fi
done
答案 5 :(得分:-1)
如果你可以使用一些额外的反斜杠,bash的printf "%q"
很有用:
X=("hello world" "goodnight moon" 'say "boo"' 'foo\bar')
json="[$(printf '"%q",' "${X[@]}")"
json="${json%,}]"
echo "$json"
["hello\ world","goodnight\ moon","say\ \"boo\"","foo\\bar"]
关于反斜杠的正确性:node.js对它们没有问题:
$ node
> x = ["hello\ world","goodnight\ moon","say\ \"boo\"","foo\\bar"]
[ 'hello world',
'goodnight moon',
'say "boo"',
'foo\\bar' ]