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

时间:2014-11-07 19:41:45

标签: 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 '.'

6 个答案:

答案 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' ]