JSON文字列でのBash変数の置換

JSON文字列でのBash変数の置換

私はBASHでJSONを作成しようとしていますが、フィールドの1つは以前のコマンドの結果に基づいています

BIN=$(cat next_entry)
OUTDIR="/tmp/cpupower/${BIN}"
echo $OUTDIR
JSON="'"'{"hostname": "localhost", "outdir": "${OUTDIR}", "port": 20400, "size": 100000}'"'"
echo $JSON

上記のスクリプトを実行すると、次が返されます。

/tmp/cpupower/0
, port: 20400, size: 100000}': /tmp/cpupower/0

これらの多重引用符で囲まれた文字列内の変数を適切に置き換えるにはどうすればよいですか?

答え1

JSON=\''{"hostname": "localhost", "outdir": "'"$OUTDIR"'", "port": 20400, "size": 100000}'\'

つまり、 の展開では一重引用符を外します$OUTDIR。スカラー変数の割り当てでは厳密には必要ではありませんが、念のため、その展開を二重引用符で囲みました。

変数を渡すときは引用符$JSONで囲みますechoechoただし、split+glob 演算子を無効にする必要があります。任意のデータの場合は、これを避けるのが最善です。

printf '%s\n' "$JSON"

答え2

AWS コマンドを使用しようとしてここにたどり着いた場合は、@Stéphane Chazelas の回答がほぼ有効です。ここでは、最初のエスケープ引用符 (\') は必要ありません。実際には、コマンドが中断されます。

IP=$(curl ipecho.net/plain ; echo)

aws ec2 authorize-security-group-ingress --group-id sg-**************** \
    --ip-permissions '[{"IpProtocol": "tcp", "FromPort": 15000, "ToPort": 15000, "IpRanges": [{"CidrIp": "'"$IP/32"'", "Description": "Service A"}]}]'

^ これで問題なく動作します

答え3

ステファンの回答は素晴らしいので、賛成です。ここにちょっとしたヒントがあります。

BIN=$(cat next_entry)

できるよ:

BIN=$(<next_entry)

これにより、余分なプロセスの生成を節約できます。続きを読むここ

答え4

eating.json=のような json ファイルがある場合{"diner" : {"time" : ""}}、次のように実行します。

declare -a NOW
NOW=$(date) 
jq '.diner.time = "'"${NOW}"'"' eating.json > tmp.$$.json && mv tmp.$$.json eating.json

そこで、まず変数を作成し、次にそこに必要な値を入れ、最後に を使用してjq一時ファイルに変更を加え (jqモジュールの特性によるものだと思います)、変更内容を に戻しましたeating.json

関連情報