heredocのJSONコンテンツを解析できないのはなぜですか?

heredocのJSONコンテンツを解析できないのはなぜですか?

JSONフラグメントがあります。

以下は機能しません:

VALUE=<<PERSON
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]"  
}
PERSON
echo -n "$VALUE" | python -m json.tool

結果:

JSONオブジェクトをデコードできません。

jqつまり、同じことを行います。

echo -n "$VALUE" | jq '.'

出力がありません。

以下は同じ動作をします。

VALUE=<<PERSON
'{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]"  
}'
PERSON
echo -n "$VALUE" | python -m json.tool

返信:

JSONオブジェクトをデコードできません。

しかし、以下はうまくいきます。

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]"
}'
echo -n "$VALUE" | jq '.'
echo -n "$VALUE" | python -m json.tool

答え1

VALUE=<<PERSON
some data
PERSON

echo "$VALUE"

出力がありません。

ここにある文書は次のとおりです。リダイレクト、変数にリダイレクトできません。

コマンドラインを解析すると、リダイレクトは変数の割り当てとは別のステップとして扱われます。したがって、あなたの命令は(スペースに注意してください)

VALUE= <<PERSON
some data
PERSON

つまり、空の文字列を変数に割り当ててから、その文字列の標準入力をコマンドにリダイレクトします(ただし、コマンドがないため何も起こりません)。

気づく

<<PERSON
some data
PERSON

そのまま有効です

<somefile

データを含むように標準入力ストリームを設定できるコマンドがないため、失われます。

しかしこれはうまくいきます:

VALUE=$(cat <<PERSON
some data
PERSON
)

ここで文書を受け取り、cat標準出力にコピーする命令は次のとおりです。これはコマンド置換によって変数に割り当てられます。

あなたの場合は、次のものを使用できます

python -m json.tool <<END_JSON
JSON data here
END_JSON

変数にデータを格納する追加の手順を実行する必要はありません。


このようなツールを見ることも価値があるかもしれません。jo正しいエンコーディングでJSONデータを生成します。

たとえば、

jo type=account customer_id=1234 [email protected] random_data="some^Wdata"

...出力される^Wリテラル文字はどこにありますか?Ctrl+W

{"type":"account","customer_id":1234,"customer_email":"[email protected]","random_data":"some\u0017data"}

したがって、質問のコマンドは次のように書くことができます。

jo type=account customer_id=1234 [email protected] |
python -m json.tool

答え2

区切られた文書はその変数を設定しないので:

$ VALUE=<<PERSON  
> {    
>   "type": "account",  
>   "customer_id": "1234",  
>   "customer_email": "[email protected]",  
> }  
> PERSON
$ echo "$VALUE" 

$

区切り文書を使用して変数に値を割り当てるには、次のものが必要です。

$ read -d '' -r VALUE <<PERSON  
{    
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "[email protected]",  
}   
PERSON

答え3

これは、JSONで使用するためにここでドキュメントを定義する方法が間違っているためです。次のように使用する必要があります。

VALUE=$(cat <<EOF
{  
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "[email protected]",  
}
EOF
)

printf "$VALUE"JSONは期待どおりにダンプする必要があります。

答え4

ドキュメントと変数はここではうまく混在しないか、少なくともこの方法では混在しません。あなたはできます...

heredocをアプリケーションの標準入力に渡す

python -m json.tool <<PERSON  
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]",
}
PERSON

または…

シェル変数に複数行のテキストを保存する

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "[email protected]",
}'

内部二重引用符をエスケープする必要がないように単一引用符を使用します。もちろん、パラメータを拡張する必要がある場合は、二重引用符を使用することもできます。

VALUE="{
  \"type\": \"account\",
  \"customer_id\": ${ID},
  \"customer_email\": \"${EMAIL}\",
}"

その後、後で対応する変数値を使用できます。

echo -n "$VALUE" | python -m json.tool

関連情報