सवाल एक चर के लिए जटिल बहु लाइन स्ट्रिंग लिखने के लिए साफ तरीका


मुझे कुछ जटिल एक्सएमएल को एक बैश स्क्रिप्ट के अंदर एक चर में लिखना होगा। एक्सएमएल को बैश स्क्रिप्ट के अंदर पठनीय करने की आवश्यकता है क्योंकि यह वह जगह है जहां एक्सएमएल खंड जीवित रहेगा, इसे किसी अन्य फ़ाइल या स्रोत से नहीं पढ़ा जा रहा है।

तो मेरा सवाल यह है कि यदि मेरे पास एक लंबी स्ट्रिंग है जो मैं अपने बैश स्क्रिप्ट के अंदर मानव पठनीय होना चाहता हूं तो इसके बारे में जाने का सबसे अच्छा तरीका क्या है?

आदर्श रूप में मैं चाहता हूं:

  • किसी भी पात्र से बचने के लिए नहीं है
  • यह मानव पठनीय बनाने के लिए कई लाइनों में तोड़ दिया है
  • इसे इंडेंटेशन रखें

क्या यह ईओएफ या कुछ के साथ किया जा सकता है, क्या कोई मुझे एक उदाहरण दे सकता है?

जैसे

String = <<EOF
 <?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
EOF

94
2017-10-08 10:54


मूल


मैं यह शर्त लगाने के लिए तैयार हूं कि आप उस डेटा को फिर से स्ट्रीम में डंप करने जा रहे हैं। इसे एक चर में क्यों स्टोर करें जब आप चीजों को और अधिक जटिल बना सकते हैं और धाराओं का उपयोग कर सकते हैं? - Zenexer
इसे भी देखें: अतिरिक्त स्थान के साथ बहु लाइन स्ट्रिंग (संरक्षित इंडेंटेशन) - Yibo Yang


जवाब:


यह उद्धरण से बचने के बिना आपके पाठ को आपके चर में डाल देगा। यह असंतुलित उद्धरणों को भी संभालेगा (apostrophes, यानी। ')। सेंटीनेल (ईओएफ) के आस-पास उद्धरण डालकर पाठ को पैरामीटर विस्तार से गुजरने से रोकता है। -d'' इसे कई लाइनों को पढ़ने का कारण बनता है (न्यूलाइन को अनदेखा करें)। read एक बैश अंतर्निहित है इसलिए इसे बाहरी कमांड को कॉल करने की आवश्यकता नहीं है cat

IFS='' read -r -d '' String <<"EOF"
<?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
EOF

123
2017-10-08 12:37



से बचने के लिए +1 cat। - James Sneeringer
cat एक बाहरी आदेश है। इसका उपयोग नहीं कर रहा है। इसके अलावा, कुछ के पास दर्शन है कि यदि आप कम से कम दो तर्कों के साथ बिल्ली का उपयोग कर रहे हैं तो "उर डिन" यह गलत है (जो "बेकार उपयोग से अलग है" cat")। - Dennis Williamson
और कभी भी दूसरी ईओएफ इंडेंट नहीं .... .... सिर बैंग्स के लिए कई टेबल शामिल) - IljaBek
मैंने उपर्युक्त कथन का उपयोग करने की कोशिश की set -e। ऐसा लगता है read हमेशा शून्य शून्य देता है। आप इस व्यवहार को उपयोग करके मोटा कर सकते हैं ! read -d ....... - krissi
और यदि आप इस बहु-रेखा का उपयोग कर रहे हैं String एक फ़ाइल को लिखने के लिए परिवर्तनीय, वैरिएबल को "QUOTES" के आस-पास रखें echo "${String}" > /tmp/multiline_file.txt या echo "${String}" | tee /tmp/multiline_file.txt। इसे खोजने के लिए मुझे एक घंटे से अधिक समय लगा। - Aditya


आप लगभग वहाँ रहे हैं। या तो आप उपयोग करते हैं बिल्ली अपनी स्ट्रिंग की असेंबली के लिए या आप पूरी स्ट्रिंग को उद्धृत करते हैं (इस स्थिति में आपको अपनी स्ट्रिंग के अंदर उद्धरण से बचना होगा):

#!/bin/sh
VAR1=$(cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
  <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
  <caption>This is Raphael's "Foligno" Madonna, painted in
  <date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
)

VAR2="<?xml version=\"1.0\" encoding='UTF-8'?>
<painting>
  <img src=\"madonna.jpg\" alt='Foligno Madonna, by Raphael'/>
  <caption>This is Raphael's \"Foligno\" Madonna, painted in
  <date>1511</date>-<date>1512</date>.</caption>
</painting>"

echo "${VAR1}"
echo "${VAR2}"

25
2017-10-08 11:14



दुर्भाग्यवश, "राफेल" में एस्ट्रोफ़े पहले व्यक्ति को काम नहीं करता है। - Dennis Williamson
अंततः दोनों कार्य मेरे लिए काम करते हैं। VAR1 में एकल उद्धरण एक समस्या नहीं होनी चाहिए (कम से कम बाश के लिए नहीं)। शायद आपको सिंटैक्स हाइलाइटिंग द्वारा गुमराह किया गया है? - joschi
यह एक स्क्रिप्ट में काम करता है, लेकिन बैश प्रॉम्प्ट पर नहीं। स्पष्ट नहीं होने के लिए खेद है। - Dennis Williamson
ईओएफ को उद्धृत करना बेहतर है 'EOF' या "EOF", अन्यथा खोल चर को पार्स किया जाएगा। - Stanislav German-Evtushenko


#!/bin/sh

VAR1=`cat <<EOF
<?xml version="1.0" encoding='UTF-8'?>
<painting>
  <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
  <caption>This is Raphael's "Foligno" Madonna, painted in
  <date>1511</date>-<date>1512</date>.</caption>
</painting>
EOF
`
echo "VAR1: ${VAR1}"

यह बोर्न शैल पर्यावरण के भीतर ठीक काम करना चाहिए


9
2017-09-05 15:54



इस समाधान को +1 करें वैरिएबल प्रतिस्थापन जैसे $ {foo} - Offirmo
ऊपर: sh-compatible। डाउनसाइड: बैटिक्स को बैश में बहिष्कृत / निराश किया जाता है। अब अगर मुझे sh और bash के बीच चयन करना था ... - Zenexer
जब बैकटिक्स बहिष्कृत / निराश होते हैं? बस उत्सुक - Alexander Mills


फिर भी ऐसा करने का एक और तरीका ...

मैं चर और विशेष का उपयोग करना पसंद करता हूँ <<- कौन छोड़ता है तालिका बनाना स्क्रिप्ट इंडेंटेशन की अनुमति देने के लिए प्रत्येक पंक्ति की शुरुआत में:

#!/bin/bash

mapfile Pattern <<-eof
        <?xml version="1.0" encoding='UTF-8'?>
        <painting>
          <img src="%s" alt='%s'/>
          <caption>%s, painted in
          <date>%s</date>-<date>%s</date>.</caption>
        </painting>
        eof

while IFS=";" read file alt caption start end ;do
    printf "${Pattern[*]}" "$file" "$alt" "$caption" "$start" "$end"
  done <<-eof
        madonna.jpg;Foligno Madonna, by Raphael;This is Raphael's "Foligno" Madonna;1511;1512
        eof

चेतावनी: कोई नहीं है खाली जगह से पहले eof लेकिन सिर्फ तालिका बनाना

<?xml version="1.0" encoding='UTF-8'?>
 <painting>
   <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
   <caption>This is Raphael's "Foligno" Madonna, painted in
   <date>1511</date>-<date>1512</date>.</caption>
 </painting>
कुछ स्पष्टीकरण:
  • mapfile पूरे पढ़ें यहां दस्तावेज़ एक सरणी में
  • वाक्यविन्यास "${Pattern[*]}" इस सरणी को एक स्ट्रिंग में डालें।
  • मैं उपयोग करता हूं IFS=";" क्योंकि यहां नहीं है ; आवश्यक तारों में
  • वाक्यविन्यास while IFS=";" read file ... रोकना IFS बाकी लिपि के लिए संशोधित किया जाना है। इसमें, केवल read संशोधित का प्रयोग करें IFS
  • कोई कांटा नहीं

4
2017-07-22 13:45



ध्यान दें कि mapfile बैश 4 या उच्चतम की आवश्यकता है। और वाक्यविन्यास "${Pattern[*]}" सरणी को एक स्ट्रिंग में रखता है उद्धरण में कब (जैसा कि उदाहरण कोड में दिखाया गया है)। - Dennis Williamson
हां, बैश 4 बहुत था नया जब यह सवाल पूछा गया था। - F. Hauri


कई अन्य उत्तरों में बहुत से कोने के मामले हैं।

पूरी तरह से सुनिश्चित करने के लिए रिक्त स्थान, टैब, आईएफएस इत्यादि के साथ कोई समस्या नहीं है, "हेरेडोक" निर्माण का उपयोग करने के लिए एक बेहतर तरीका है, लेकिन हेड्रोक का उपयोग करके हेड्रोक की सामग्री को एन्कोड करें uuencode जैसा कि यहां बताया गया है:

https://stackoverflow.com/questions/6896025/#11379627


2
2018-05-17 09:10