Linuxでjson文字列を変数として使用する方法

Linuxでjson文字列を変数として使用する方法

小さなスクリプトがあります。

ABC=100000
DFG=600000

JSON="[{"Address":"$ABC","Backup":false,"name":"$ABC:11011","port":6745,"targetId":"$DFG","weight":1}]"

echo $JSON

私が得た結果は次のとおりです。

[{Address:$ABC,Backup:false,name:$ABC:11011,port:6745,targetId:$DFG,weight:1}]

この場合、誰でも私を助けることができますか? TIA

答え1

二重引用符で囲まれた文字列に二重引用符が含まれています。

保持したいすべての内部引用符をエスケープできます。

JSON="[{\"Address\":\"$ABC\",\"Backup\":false,\"name\":\"$ABC:11011\",\"port\":6745,\"targetId\":\"$DFG\",\"weight\":1}]"

一重引用符で囲まれた文字列を使用して、変数の位置を区別できます(読みにくい)。

JSON='[{"Address":"'"$ABC"'","Backup":false,"name":"'"$ABC"':11011","port":6745,"targetId":"'"$DFG"'","weight":1}]'

一重引用符で囲まれたフォーマット文字列でprintfを使用できます。

printf -v JSON '[{"Address":"%s","Backup":false,"name":"%s:11011","port":6745,"targetId":"%s","weight":1}]' "$ABC" "$ABC" "$DFG"

または、JSON処理ツールを使用して、変数値を持つすべての極端なケースを処理します。

JSON=$(
  jq -n -c --arg a "$ABC" --arg b "$DFG" '[{
    Address: $a, 
    Backup: false,
    name: ($a + ":11011"),
    port: 6745,
    targetId: $b,
    weight: 1
  }]'
)
echo "$JSON"

出力

[{"Address":"100000","Backup":false,"name":"100000:11011","port":6745,"targetId":"600000","weight":1}]

答え2

JSONドキュメントにシェル変数の値を挿入すると、エンコーディングの特別な値が欠落しているため、JSON文字列が破損する可能性があります。 JSON 認識ツールを使用して JSON ドキュメントを生成し、必要な値を挿入する方が良いと信頼性があります。

jq単純なテンプレートを使用してJSONドキュメントを作成します。

ABC=100000
DFG=600000

jq -n \
    --arg Address  "$ABC" \
    --arg targetId "$DFG" \
    --arg name     "$ABC:11011" \
    '[ $ARGS.named + { Backup: false, port: 6745, weight: 1 } ]'

出力(「コンパクト」出力を取得するにはjqwithを使用):-c

[
  {
    "Address": "100000",
    "targetId": "600000",
    "name": "100000:11011",
    "Backup": false,
    "port": 6745,
    "weight": 1
  }
]

これにより、値を含むいくつかの名前付きフィールドを追加する静的オブジェクトである単一要素の配列が作成されます。フィールド名(キー)とその値は--arg key valueコマンドラインで再利用されます。

これを使用してJSON文書を生成するので、同様の値(引用符、改行、タブなどが含まれている場合)を保持しているjq場合でもまだ機能します。ABC100 "My Road"

答え3

また、ここにあるドキュメントを使用してJSON構造の拡張形式で変数を埋めることができ、人々が読みやすく保守しやすくなり、引用を避けるために多くのバックスラッシュを使用せずに中間のシェル変数の値を変更できます。できます。キャラクター:

f_name=Sotto
l_name=Voce
JSON=$(cat - <<EOJSON
{
  "first_name": "${f_name}",
  "last_name": "${l_name}",
  "full_name": "${f_name} ${l_name}"
}
EOJSON
)

次に、次のようにecho "${JSON}"出力echo "$JSON"します。

{
  "first_name": "Sotto",
  "last_name": "Voce",
  "full_name": "Sotto Voce"
}

私のプライベートスタイルは変数名の周りに中かっこを使用しますが、ここでは必要ありません。$f_nameこの場合も動作します。

私はここでドキュメントを文字列参照の別のタイプとして考え始めました。完全な文字列は一重引用符または二重引用符を使用して引用符を付けられないため、通常は逆引用符を使用してエスケープする必要はありません。

関連情報