HSONoc से 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 बना देगा
निक टी

@ ध्यान दें कि आपको यह उत्तर देना चाहिए क्योंकि मुझे लगता है कि समस्या ठीक है।
rrauenza

यदि यह (एकमात्र) उत्तर है तो संभवतः इसे बंद कर दिया जाना चाहिए क्योंकि "पुन: पेश नहीं किया जा सकता है (एक टाइपो)"। हालांकि, ऐसा लग रहा है कि कुसा और टेर्डन के जवाब में असाइनमेंट + पुनर्निर्देशन का उल्लेख पूरी तरह से टूट गया है, इसलिए आपको एक खाली स्ट्रिंग मिलती है, इसलिए दो समस्याएं हैं, दोनों एक ही "नो जोंस ..." त्रुटि देंगे। मध्य में अपनी मान्यताओं की जाँच करके समस्याओं को सुलझाना बहुत अच्छा है: echo $VALUEबिना ... | jqजानकारी के एक सरल ।
निक टी।

@NickT: यह एक कॉपी / पेस्ट मुद्दा था। भ्रम के लिए खेद है
जिम

जवाबों:


19
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

एक चर में डेटा संग्रहीत करने का अतिरिक्त कदम उठाए बिना।


2
तुम भी सिर्फ PERSON="एक newline और मल्टी-लाइन डेटा द्वारा पीछा किया जा सकता है , तो "अंत में एक और ।
आर .. गिटहब स्टॉप हेल्पिंग ICE

1
@ आर .. हाँ, लेकिन यहां एक दस्तावेज़ आपको शेल के उद्धरण नियमों को बायपास करने की अनुमति देता है। इसलिए अक्सर बहु-पंक्ति डेटा के लिए एक उद्धृत स्ट्रिंग के बजाय यहाँ-दस्तावेज़ का उपयोग करना अधिक सुरक्षित होता है, खासकर यदि डेटा में एकल या दोहरे उद्धरण (या दोनों) हों।
Kusalananda

2
@R .. यह देखते हुए कि हम जिस JSON के बारे में बात कर रहे हैं, प्रत्येक संपत्ति के नाम के दोहरे उद्धरण-चिह्नों से बचने के लिए एकल उद्धरणों का उपयोग करना बेहतर हो सकता है। PERSON='। जब तक कि ओपी बाद में वैरिएबल को प्रक्षेपित नहीं करना चाहता।
जोएल

(बैकस्लैश) (न्यूलाइन) यहां दस्तावेज़ में गायब हो जाता है, भले ही आप सीमांकक शब्द को उद्धृत / बचते हों। यह वांछनीय हो सकता है, लेकिन क्या इसे अक्षम करने का कोई तरीका है?
स्कॉट

@ यदि यह प्रश्न इस साइट पर पहले नहीं पूछा गया है, तो यह अपने आप में एक उत्कृष्ट प्रश्न होगा।
Kusalananda

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 डेटा क्यों लपेट रहे हैं? यह वास्तव में ऐसा नहीं लगता है कि ओपी उन्हें अपने इनपुट स्ट्रिंग का हिस्सा बनाना चाहता है। इसके अलावा, बेघर बिल्ली की आबादी को कम करने के लिए +1। कुसलानंद के जवाब के साथ, आप लाइनों के सिरों पर इनपुट और बैकस्लैश में एस << \PERSONसे बचाने के लिए सुझाव देना चाह सकते हैं $
स्कॉट

@ Ccott उम, क्योंकि मैं नेत्रहीन ओपी से पाठ की नकल करता हूं। धन्यवाद
terdon

3
यह सही जवाब है। $(cat <<EOF ... EOF)एक अजीब निर्माण है: एक उपधारा चल रहा है और फिर बिल्ली को एक हेरेडोक भेज रहा है ताकि वह इसे एसटीडीयूएसटी के लिए भेज दे और फिर उस उपसमूह के परिणाम को एक चर में नियत कर दे? काश लोग अपने विचार प्रक्रियाओं के बारे में जो कुछ कह रहे हैं, उसके बारे में सोचते होंगे। readतुलना के माध्यम से एक चर के लिए एक वंशानुगत असाइन करना , समझदार है।
रिच

मैं यह नहीं कहूंगा कि $(cat << EOF... (डेटा) ... EOF )अजीब है। यह अजीब और विवादास्पद है, लेकिन ऐसा है read -d … << EOF - विशेष रूप से read -d '' << EOF । मैं टेर्डन के उत्तर की सराहना करता हूं क्योंकि यह केवल बिल्डिंस का उपयोग करता है, कोई कार्यक्रम नहीं। लेकिन, इससे भी महत्वपूर्ण बात यह है कि, $(cat << EOF(डेटा) ... EOF )विफल रहता है अगर कोई भी रेखा \(बैकस्लैश) के साथ समाप्त होती है - कुसलानंद के उत्तर के तहत टिप्पणियों को देखें ।
स्कॉट

5

इसका कारण यह है कि जिस तरह से आपने JSON के साथ उपयोग करने के लिए यहां-डॉको परिभाषित किया है वह गलत है। आपको इसका उपयोग करने की आवश्यकता है

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

और printf "$VALUE"उम्मीद के मुताबिक JSON को डंप करना चाहिए।


3

Heredocs और वैरिएबल अच्छी तरह से या कम से कम इस तरह से मिश्रण नहीं करते हैं। आप या तो यह कर सकते हैं…

एक आवेदन के मानक इनपुट के रूप में हेरेडोक पास करें

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.