如何将 bash 数组格式化为 JSON 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26808855/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to format a bash array as a JSON array
提问by Jon
I have a bash array
我有一个 bash 数组
X=("hello world" "goodnight moon")
That I want to turn into a json array
我想变成一个 json 数组
["hello world", "goodnight moon"]
Is there a good way for me to turn this into a json array of strings without looping over the keys in a subshell?
有没有什么好方法可以将它转换为字符串的 json 数组,而无需在子 shell 中遍历键?
(for x in "${X[@]}"; do; echo $x | sed 's|.*|"&"|'; done) | jq -s '.'
This clearly doesn't work
这显然不起作用
echo "${X[@]}" | jq -s -R '.'
回答by kev
You can do this:
你可以这样做:
X=("hello world" "goodnight moon")
printf '%s\n' "${X[@]}" | jq -R . | jq -s .
output
输出
[
"hello world",
"goodnight moon"
]
回答by John Bollinger
This ...
这个 ...
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[@]}"
... yields:
...产量:
["hello world", "goodnight moon", "say \"boo\"", "foo\bar"]
If you are planning to do a lot of this (as your reluctance to use a subshell suggests) then something such as this that does not rely on anysubprocess is likely to your advantage.
如果您打算做很多这样的事情(正如您不愿使用子shell 所暗示的那样),那么诸如此类的不依赖于任何子进程的事情可能对您有利。
回答by nisetama
If the values do not contain ASCII control characters, which have to be escaped in strings in valid JSON, you can also use sed
:
如果值不包含 ASCII 控制字符,这些字符必须在有效 JSON 的字符串中转义,您还可以使用sed
:
$ X=("hello world" "goodnight moon")
$ printf %s\n "${X[@]}"|sed 's/["\]/\&/g;s/.*/"&"/;1s/^/[/;$s/$/]/;$!s/$/,/'
["hello world",
"goodnight moon"]
If the values contain ASCII control characters, you can do something like this:
如果值包含 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
回答by anubhava
You can use:
您可以使用:
X=("hello world" "goodnight moon")
sed 's/^/[/; s/,$/]/' <(printf '"%s",' "${X[@]}") | jq -s '.'
[
[
"hello world",
"goodnight moon"
]
]
回答by glenn Hymanman
If you're OK with a few extra backslashes, bash's printf "%q"
is useful:
如果您可以使用一些额外的反斜杠,那么 bashprintf "%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"]
Regarding the OK-ness of the backslashes: node.js doesn't have a problem with them:
关于反斜杠的正常性:node.js 没有问题:
$ node
> x = ["hello\ world","goodnight\ moon","say\ \"boo\"","foo\bar"]
[ 'hello world',
'goodnight moon',
'say "boo"',
'foo\bar' ]