web-dev-qa-db-ja.com

jq&bash:変数からJSON配列を作成

jq を使用して、変数値からbashのJSONを作成しています。

プレーン変数を作成する方法を得た

$ VAR="one two three"
$ jq -n "{var:\"$VAR\"}"
{
  "var": "one two three"
}

しかし、まだ配列を作成することはできません。私が持っています

$ echo $ARR
one
two
three

のようなものを取得したい

{
  "arr": ["one", "two", "three"]
}

次のような文字化けした出力しか取得できません

$ jq -n "{arr: [\"$ARR\"]}"
{
  "arr": [
    "one\ntwo\nthree"
  ]
}

JSON配列を正しい方法で形成する方法は? jqはこれを実行できますか?

[〜#〜] edit [〜#〜]:jq 1.3のみがある場合に質問されました。さて、jq 1.4では、@ JeffMercadoや@peakが提案したように、私が要求したことをまっすぐに行うことができます。しかし、@ jbrの回答の受け入れを取り消さないでください。

20
Andrey Regentov

jqは、指示どおりに実行しています。 jqはJSONを生成するためのプログラムではなく、JSONを照会するためのツールです。 -nスイッチを使用して実行していることは、きれいなプリンターとして使用しているだけです。 したがって、「1」、「2」、「3」を含む配列を持つオブジェクトを印刷する場合は、生成する必要があります。

VAR="one two three"
VAR=$(echo $VAR | sed -e 's/\(\w*\)/,"\1"/g' | cut -d , -f 2-)
echo "{var: [$VAR]}"

更新

Bryan および他の人が以下で言及するように、jqでJSONを生成することは確かに可能であり、バージョン1.4から、OPが直接求めることさえ可能です。たとえば Jeffの答え =。

2
jbr

Jq 1.3以降では、--arg VARIABLE VALUEコマンドラインオプションを使用できます。

jq -n --arg v "$VAR" '{"foo": $v}'

つまり、--argは変数を指定された値に設定するので、jqプログラムで$varnameを使用でき、jqプログラムへのシェル変数補間を使用する必要はありません。

編集:jq 1.5以降では、--argjsonを使用して、配列を直接渡すことができます。

jq -n --argjson v '[1,2,3]' '{"foo": $v}'
24
user2259432

変数をロードしたら、 split フィルターを使用して、その文字列を配列に分割する必要があります。

$ jq -n --arg inarr "${ARR}" '{ arr: $inarr | split("\n") }'
14
Jeff Mercado

このスレッドの元の投稿には、VAR = "one two three"が記載されています。このような変数の場合、jq 1.4の非常に簡単なソリューションは次のとおりです。

$ jq -n -c -M --arg s "$VAR" '{var: ($s|split(" "))}'
{"var":["one","two","three"]}

(これはLinuxまたはMacシェルなどを想定しており、jq 1.4で動作します。)

区切り文字が改行の場合、次のTypeScriptを検討してください。

$ s=$(printf "a\nb\nc\n")
$ jq -n -c -M --arg var "$s" '{"var": ($var|split("\n"))}'
{"var":["a","b","c"]}

改行文字のJSON文字列は"\n""\\n"ではない)であることに注意してください。

3番目の興味深いケースは、VARがbash配列の場合です。この場合、「$ {VAR [@]}」を使用してアイテムを渡すことは許容できますが、一般に、「-arg name value」オプションは文字列を渡すことのみを目的としていることに注意する必要があります。

Jq> 1.4では、エクスポートされたシェル変数は、オンラインjqマニュアルページに記載されているように、「env」オブジェクトを使用して渡すことができます。

7
peak

最初に-Rを使用して生の行を読み取る必要があり、次にすべての値を-sで丸Sみする必要があります。

$ echo -e "one\ntwo\nthree" | jq -R . | jq -s '{"arr": .}'
{
  "arr": [
    "one",
    "two",
    "three"
  ]
}
3
ceving

これはjq 1.6でうまくいきました:

$ jq -nc '$ARGS.positional' --args 1 2 3
["1","2","3"]

この特定のユースケースでは、配列を使用して次のように記述できます。

$ VAR=(one two three)
$ jq -nc '{var: $ARGS.positional}' --args ${VAR[@]}
{"var":["one","two","three"]}

次のような文字列を使用することもできます。

$ VAR="one two three"
$ jq -nc '{var: ($ARGS.positional[0] | split(" "))}' --args $VAR
2
ashanbrown

次の構文を使用できます。

jq --arg keyName "MyVal" '.[]."\($keyName)"[] ./JSONFile.js

のような入力データ用

[{"MyVal":"Value1","MyVal":Value2,"NotMyVal":"Value3"}];

変数を使用してJSONから解析済みデータを取得します。

この例は印刷します:

"Value1"
"Value2"
0
alexglue