21

私はbash配列を持っています

X=("hello world" "goodnight moon")

json配列にしたいこと

["hello world", "goodnight moon"]

サブシェルのキーをループせずに、これを文字列の json 配列に変換する良い方法はありますか?

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

これは明らかに機能しません

echo "${X[@]}" | jq -s -R '.'
4

7 に答える 7

40

あなたはこれを行うことができます:

X=("hello world" "goodnight moon")
printf '%s\n' "${X[@]}" | jq -R . | jq -s .

出力

[
  "hello world",
  "goodnight moon"
]
于 2014-11-07T20:10:20.893 に答える
8

jq 1.6以降、これを行うことができます:

jq --compact-output --null-input '$ARGS.positional' --args "${X[@]}"

与える:

["hello world","goodnight moon"]

これには、エスケープがまったく必要ないという利点があります。改行、タブ、二重引用符、バックスラッシュ、およびその他の制御文字を含む文字列を処理します。(まあ、NUL 文字は処理しませんが、そもそもそれらを bash 配列に含めることはできません。)

于 2021-05-11T14:55:55.820 に答える
7

これ ...

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"]

これをたくさん実行する予定がある場合 (サブシェルの使用に消極的であることからもわかるように)、サブプロセスに依存しないこのようなものが有利になる可能性があります。

于 2014-11-07T20:07:23.707 に答える
1

以下を使用できます。

X=("hello world" "goodnight moon")
sed 's/^/[/; s/,$/]/' <(printf '"%s",' "${X[@]}") | jq -s '.'
[
  [
    "hello world",
    "goodnight moon"
  ]
]
于 2014-11-07T19:57:17.647 に答える
0

バックスラッシュをいくつか追加しても問題ない場合は、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"]

バックスラッシュの OK-ness について: node.js には問題はありません。

$ node
> x = ["hello\ world","goodnight\ moon","say\ \"boo\"","foo\\bar"]
[ 'hello world',
  'goodnight moon',
  'say "boo"',
  'foo\\bar' ]
于 2014-11-07T20:12:48.803 に答える