Yorumlu yazılımdaki JSON içeriği neden ayrıştırılamıyor?


12

Bir JSON parçam var.

Aşağıdakiler çalışmaz:

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

Sonuç:

Hiçbir JSON nesnesinin kodu çözülemedi

Aynısını yapmak jq, yani

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

Çıktı yok.

Aşağıdakiler için aynı davranış vardır:

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

Tepki:

Hiçbir JSON nesnesinin kodu çözülemedi

Ancak aşağıdakiler işe yarar:

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

5
Bash'ın ne yaptığını bilmiyorum, ancak ilk ikinizdeki e-posta dizesinden sonra bir izleyen virgül var, ancak üçüncü değil, ilk çift yasadışı JSON
Nick T

@NickT, tam olarak sorun olduğunu düşündüğüm gibi bir cevap vermelisin.
rrauenza

Eğer (tek) cevap buysa, muhtemelen "çoğaltılamaz (bir yazım hatası)" olarak kapatılmalıdır. Ancak, Kusa'nın ve terdon'un cevabının atama + yeniden yönlendirme tamamen bozuk olduğunu belirtiyor gibi görünüyor, bu yüzden boş bir dize elde edersiniz, bu nedenle her ikisi de aynı "JSON Yok ..." hatasını verecek iki sorun vardır. Varsayımlarınızı ortada kontrol ederek sorunları ikiye bölmek çok iyi bir uygulamadır: basit echo $VALUEolmayan bir ... | jqbilgilendirici olacaktır.
Nick T

@NickT: Bu bir kopyalama / yapıştırma sorunuydu. Karışıklık için üzgünüm
Jim

Yanıtlar:


20
VALUE=<<PERSON
some data
PERSON

echo "$VALUE"

Çıktı yok.

Buradaki belge bir yönlendirmedir , bir değişkene yönlendiremezsiniz.

Komut satırı ayrıştırıldığında, yönlendirmeler değişken atamalardan ayrı bir adımda işlenir. Bu nedenle komutunuz eşdeğerdir (boşluğu not edin)

VALUE= <<PERSON
some data
PERSON

Yani, değişkeninize boş bir dize atar, daha sonra burada-dizeden standart girdiyi komuta yönlendirir (ancak komut yoktur, bu yüzden hiçbir şey olmaz).

Bunu not et

<<PERSON
some data
PERSON

olduğu gibi geçerlidir

<somefile

Sadece standart girdi akışı verileri içerecek şekilde ayarlanabilen bir komut yoktur, bu yüzden kaybolur.

Bu olsa işe yarar:

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

Burada, burada belgeyi alan komut catve standart çıktısına kopyalar. Bu, komut değiştirme ile değişkene atanan şeydir.

Sizin durumunuzda,

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

bir değişkende veri saklamak için fazladan bir adım atmadan.


joDoğru kodlama ile JSON verisi oluşturmak gibi araçlara bakmak da faydalı olabilir :

Örneğin:

jo type=account customer_id=1234 customer_email=jim@gmail.com random_data="some^Wdata"

... ^Wgerçek bir Ctrl+Wkarakter nerede çıktı

{"type":"account","customer_id":1234,"customer_email":"jim@gmail.com","random_data":"some\u0017data"}

Yani sorudaki komut yazılabilirdi

jo type=account customer_id=1234 customer_email=jim@gmail.com |
python -m json.tool

2
Ayrıca PERSON="bir satırsonu satırı ve çok satırlı veriler, sonra "da son satırda başka bir satır yapabilirsiniz .
R .. GitHub BUZA YARDIMCI DURDUR

1
@R .. Evet, ama burada bir belge, kabuğun alıntı kurallarını atlamanızı sağlar. Bu nedenle, özellikle veriler tek veya çift tırnak (veya her ikisi) içeriyorsa, çok satırlı veriler için tırnak içine alınmış bir dize yerine burada bir belgenin kullanılması genellikle daha güvenlidir.
Kusalananda

2
@R .. Bahsettiğimiz JSON olduğu için, her bir mülk adının çift tırnaklarından kaçmak zorunda kalmamak için tek tırnak işareti kullanmak daha iyi olabilir. PERSON='. OP daha sonra değişkenleri enterpole etmek istemedikçe budur.
JoL

(ters eğik çizgi) (satırsonu), sınırlayıcı kelimeyi alıntılasanız / kaçarsanız bile, bu belgede yok gibi görünüyor. Bu arzu edilebilir, ancak devre dışı bırakmanın herhangi bir yolu var mı?
Scott

@Scott Bu soru daha önce bu sitede sorulmamışsa, kendi başına mükemmel bir soru olurdu.
Kusalananda

11

Değişken heredoc tarafından ayarlanmadığı için:

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

$

Bir değişkene değer atamak için bir yorumlu metin kullanmak istiyorsanız, aşağıdakine benzer bir şeye ihtiyacınız vardır:

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

1
Neden JSON verilerini tek tırnak içine alıyor musunuz? OP'nin giriş dizesinin bir parçası olmalarını istemiyor gibi görünmüyor. Bunun yanı sıra, evsiz kedi nüfusunu azaltmak için +1. Kusalananda'nın cevabında olduğu gibi, girişteki s'ye ve satır sonlarındaki ters eğik çizgilere << \PERSONkarşı korunmayı önermek isteyebilirsiniz $.
Scott

@Scott um, çünkü metni OP'den körü körüne kopyaladım. Thanks
terdon

3
Bu doğru cevap. $(cat <<EOF ... EOF)garip bir yapıdır: bir alt kabuk çalıştırmak ve daha sonra kediye bir yorumlu metin göndermek böylece STDOUT'a gönderir ve sonra bu alt kabuğun sonucunu bir değişkene atar? İnsanların düşünce süreçleri hakkında söylediklerini düşünmelerini isterdim . Karşılaştırmalı olarak bir değişkene bir yorumlu metin atamak akılcıdır read.
Zengin

Ben öyle demezdim $(cat << EOF(veri) ... ... EOF )garip. Garip ve kıvrımlı, ama öyle read -d … << EOF - özellikle read -d '' << EOF . Terdon'un cevabını takdir ediyorum çünkü sadece yerleşikleri kullanıyor, program kullanmıyor. Ancak, daha da önemlisi, $(cat << EOF… (veri)… EOF )herhangi bir satır \(ters eğik çizgi) ile biterse başarısız olur - Kusalananda'nın cevabı altındaki yorumlara bakın .
Scott

5

Bunun nedeni, bir JSON ile kullanmak için bir burada-doc tanımlama biçiminizin yanlış olmasıdır. Olarak kullanmanız gerekir

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

ve yapmak printf "$VALUE"JSON'u beklendiği gibi boşaltmalıdır.


3

Yorumlu metinler ve değişkenler iyi karışmaz veya en azından bu şekilde karışmaz. Ya yapabilirsiniz…

Heredoc'u bir uygulamanın standart girdisi olarak geçirin

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

veya…

Çok satırlı metni kabuk değişkeninde saklama

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

Ben iç çift tırnak kaçmak ihtiyacını önlemek için tek tırnak kullandım. Elbette, örneğin parametreleri genişletmeniz gerekiyorsa, çift tırnak işaretleri de kullanabilirsiniz:

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

Daha sonra değişken değerini daha sonra kullanabilirsiniz.

echo -n "$VALUE" | python -m json.tool
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.