ヒアドキュメントのJSONコンテンツが解析できないのはなぜですか?


11

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

以下は機能しません。

VALUE=<<PERSON
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com"  
}
PERSON
echo -n "$VALUE" | python -m json.tool

結果は次のとおりです。

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

で同じことを行うjq、すなわち

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

出力はありません。

以下についても同じ動作があります。

VALUE=<<PERSON
'{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com"  
}'
PERSON
echo -n "$VALUE" | python -m json.tool

応答:

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

しかし、次の作品:

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com"
}'
echo -n "$VALUE" | jq '.'
echo -n "$VALUE" | python -m json.tool

5
最初のカップル違法JSON作ることになる、私はbashがやっているのか分からないが、末尾のカンマは、あなたの最初の2における電子メールの文字列の後ではなく、第三にあります
ニック・T

@NickTそれは正確に問題だと思うので、あなたはそれを答えにするべきです。
ラウエンツァ

それが(唯一の)答えである場合、おそらく「再現できない(タイプミス)」として閉じられるべきです。ただし、Kusaとterdonの回答では割り当て+リダイレクトが完全に壊れているため、空の文字列が取得されるため、2つの問題があり、どちらも同じ「JSONなし...」エラーが発生するようです。それは途中であなたの仮定をチェックすることで二分問題に非常に良い練習です:シンプルecho $VALUEなし ... | jq有益だろう。
Nick T

@NickT:それはコピー/貼り付けの問題でした。混乱してごめんなさい
ジム

回答:


19
VALUE=<<PERSON
some data
PERSON

echo "$VALUE"

出力はありません。

ヒアドキュメントはリダイレクトです。変数にリダイレクトすることはできません。

コマンドラインが解析されると、リダイレクトは変数の割り当てとは別のステップで処理されます。あなたのコマンドは(スペースに注意)することと等価です

VALUE= <<PERSON
some data
PERSON

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

ご了承ください

<<PERSON
some data
PERSON

であるとして、有効です

<somefile

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

しかしこれは動作します:

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

ここでは、ヒアドキュメントを受け取るコマンドはcatであり、それを標準出力にコピーします。これは、コマンド置換によって変数に割り当てられるものです。

あなたのケースでは、代わりに使用できます

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

変数にデータを格納する追加の手順を実行することなく。


2
またPERSON="、改行と複数行のデータを続け"、最後に別の行を続けることもできます。
R .. GitHub ICE HELPING ICEの停止

1
@R ..はい。ただし、ヒアドキュメントを使用すると、シェルの引用ルールをバイパスできます。したがって、特にデータに一重引用符または二重引用符(またはその両方)が含まれている場合は、複数行データの引用文字列ではなくヒアドキュメントを使用する方が安全です。
クサラナンダ

2
@R ..話しているのはJSONなので、各プロパティ名の二重引用符をエスケープする必要がないように、単一引用符を使用する方がよい場合があります。PERSON='。これは、OPが後で変数を補間する必要がない限りです。
JoL 2018

(バックスラッシュ)(改行)は、区切り文字を引用/エスケープしても、ヒアドキュメントでは消えているようです。それは望ましいかもしれませんが、それを無効にする方法はありますか?
スコット

@Scottもしこの質問がこのサイトで以前に聞かれたことがないなら、それ自体が素晴らしい質問でしょう。
クサラナナンダ

11

変数がヒアドキュメントによって設定されていないため:

$ VALUE=<<PERSON  
> {    
>   "type": "account",  
>   "customer_id": "1234",  
>   "customer_email": "jim@gmail.com",  
> }  
> PERSON
$ echo "$VALUE" 

$

ヒアドキュメントを使用して変数に値を割り当てる場合は、次のようなものが必要です。

$ read -d '' -r VALUE <<PERSON  
{    
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "jim@gmail.com",  
}   
PERSON

1
JSONデータを単一引用符で囲むのはなぜですか?OPが入力文字列の一部になることをOPが望んでいるようには見えません。それとは別に、ホームレス猫の数を減らすための+1。Kusalanandaの答えと同様に、入力のs や行末のバックスラッシュ<< \PERSONから保護することを提案したい場合が$あります。
スコット

@スコットええと、私は盲目的にOPからテキストをコピーしたからです。ありがとう
terdon

3
これは正しい答えです。$(cat <<EOF ... EOF)は奇妙な構造です:サブシェルを実行し、ヒアドキュメントをcatに送信してSTDOUTに送信し、そのサブシェルの結果を変数に割り当てますか?私は人々が彼らの思考プロセスについて彼らが言っていることについて考え欲しいですread比較すると、を介してヒアドキュメントを変数に割り当てるのは、まともです。
リッチ

$(cat << EOF…(データ)… EOF )は変だとは言えません。扱いにくく複雑ですが、read -d … << EOF 特にそうですread -d '' << EOF 。terdonの答えは、組み込みプログラムのみを使用し、プログラムは使用しないため、ありがたいです。しかし、より重要なのは、$(cat << EOF…(データ)… (バックスラッシュ)でEOF )終わる行があると失敗することです。Kusalanandaの回答の\下のコメントを参照してください。
スコット

4

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

VALUE=$(cat <<EOF
{  
  "type": "account",  
  "customer_id": "1234",  
  "customer_email": "jim@gmail.com",  
}
EOF
)

実行するとprintf "$VALUE"、JSONが期待どおりにダンプされます。


3

ヒアドキュメントと変数はうまく混合しないか、少なくともこのように混合しません。あなたはどちらか…

ヒアドキュメントをアプリケーションの標準入力として渡す

python -m json.tool <<PERSON  
{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com",
}
PERSON

または…

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

VALUE='{
  "type": "account",
  "customer_id": "1234",
  "customer_email": "jim@gmail.com",
}'

内側の二重引用符をエスケープする必要を避けるために、単一引用符を使用しました。もちろん、たとえばパラメータを展開する必要がある場合は、二重引用符を使用することもできます。

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

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

echo -n "$VALUE" | python -m json.tool
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.