कैसे बैश में एक बहुपरत स्ट्रिंग उत्पादन करने के लिए?


250

मैं कैसे कई इको कॉल का उपयोग किए बिना बैश में एक मल्टीप्लेयर स्ट्रिंग आउटपुट कर सकता हूं:

echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo 
echo "Report bugs to: "
echo "up home page: "

मैं ऐसा करने के लिए एक पोर्टेबल तरीका ढूंढ रहा हूं, केवल बैश बिल्डिंस का उपयोग करके।


4
यदि आप एक गलत मंगलाचरण के जवाब में एक उपयोग संदेश का उत्पादन कर रहे हैं, तो आप सामान्य रूप से मानक त्रुटि के बजाय मानक त्रुटि के लिए उस संदेश को भेजेंगे,echo >&2 ...
मार्क रीड रीड

2
@MarkReed उपयोग संदेश टाइप करके आउटपुट होता है --help(जिसे मानक से बाहर जाना चाहिए)।
हेल्परमेथोड

साथ आने वाले अन्य लोगों के लिए, "यहाँ दस्तावेज़" के बारे में अधिक जानकारी उपलब्ध है: tldp.org/LDP/abs/html/here-docs.html
जेफरी मार्टिनेज

printfगॉर्डन डेविडसन से -based समाधान की जाँच करें । echoया catआधारित दृष्टिकोण की छाया में होने के बावजूद , यह एक कीचड़ से बहुत कम लगता है। मोटे तौर पर `प्रिंटफ 'वाक्य-विन्यास एक सीखने की अवस्था का एक सा प्रतिनिधित्व करता है, लेकिन मैं अन्य कमियों (संगतता, प्रदर्शन, प्रदर्शन ...) का कान करना चाहूंगा
mjv

जवाबों:


296

इस उद्देश्य के लिए अक्सर दस्तावेजों का उपयोग किया जाता है।

cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page:
EOF

उन्हें बैश के सभी संस्करणों सहित सभी बॉर्न-व्युत्पन्न गोले में समर्थित हैं।


4
हाँ - लेकिन catएक अंतर्निहित नहीं है।
मार्क रीड

8
@MarkReed: यह सच है, लेकिन यह हमेशा उपलब्ध है (संभवतः असामान्य परिस्थितियों में छोड़कर)।
अगली सूचना तक रोक दिया गया।

6
+1 Thx। मैंने read -d '' help <<- EOF ...मल्टीलाइन स्ट्रिंग को एक चर में पढ़ने के लिए उपयोग किया है और फिर परिणाम को प्रतिध्वनित किया है।
हेल्परमेथोड

3
क्या मैं HEREDOC को एक चर में सहेज सकता हूं?
चॉवी

177

या आप यह कर सकते हैं:

echo "usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page: "

1
@OliverWeiler: यह भी इस तरह के डैश और के रूप में बॉर्न गोले में काम करेंगे विरासत बॉर्न शैल
अगली सूचना तक रोक दिया गया।

6
महान नहीं है अगर आपको किसी फ़ंक्शन में इसकी आवश्यकता है क्योंकि आपको या तो 1 की आवश्यकता होगी) स्ट्रिंग को अपनी फ़ाइल के बाईं ओर सभी तरह से या 2) इसे अपने बाकी कोड के साथ लाइन में रखने के लिए इंडेंट रखें, लेकिन तब यह प्रिंट करता है साथ ही इंडेंट
sg

43

इस पृष्ठ पर व्यावहारिक उत्तर से प्रेरित होकर, मैंने एक मिश्रित दृष्टिकोण बनाया, जिसे मैं सबसे सरल और अधिक लचीला मानता हूं। तुम क्या सोचते हो?

सबसे पहले, मैं एक चर में उपयोग को परिभाषित करता हूं, जो मुझे विभिन्न संदर्भों में इसका पुन: उपयोग करने की अनुमति देता है। प्रारूप बहुत सरल है, लगभग WYSIWYG, बिना किसी नियंत्रण वर्ण जोड़ने की आवश्यकता के बिना। यह मुझे काफी पोर्टेबल लगता है (मैंने इसे MacOS और Ubuntu पर चलाया)

__usage="
Usage: $(basename $0) [OPTIONS]

Options:
  -l, --level <n>              Something something something level
  -n, --nnnnn <levels>         Something something something n
  -h, --help                   Something something something help
  -v, --version                Something something something version
"

तो मैं बस के रूप में उपयोग कर सकते हैं

echo "$__usage"

या इससे भी बेहतर, जब मापदंडों को पार्स करते हैं, तो मैं इसे एक-लाइनर में इको कर सकता हूं:

levelN=${2:?"--level: n is required!""${__usage}"}

4
यह मेरे लिए एक स्क्रिप्ट में काम करता है जहाँ उपरोक्त उत्तर (संशोधन के बिना) नहीं होता है।
डेविड वेल्च

3
यह \ t और \ n जैसे वर्णों के एक समूह को शामिल करने की तुलना में बहुत साफ है, जो पाठ में खोजना मुश्किल है और आउटपुट को स्क्रिप्ट में स्ट्रिंग की तुलना में बहुत अलग बनाने के लिए है
sg

1
कुछ कारणों से यह मेरे लिए एक ही लाइन पर सब कुछ प्रिंट करता है: /
निकोलस डी फोंटेनै

2
@ निकोलस: echo "$__usage"मेरे लिए दोहरे उद्धरण चिह्नों का उपयोग करना आवश्यक था। echo $__usageकाम नहीं किया।
मारियो

24

-eविकल्प का उपयोग करें , फिर आप \nस्ट्रिंग में नई पंक्ति वर्ण मुद्रित कर सकते हैं ।

नमूना (लेकिन यकीन नहीं है कि एक अच्छा है या नहीं)

मजे की बात यह है कि -eविकल्प को अभी भी प्रयोग किए जाने के दौरान मैकओएस के मैन पेज में प्रलेखित नहीं किया गया है । यह लिनक्स के मैन पेज में प्रलेखित है ।


6
वे मैन पेज सिस्टम-सप्लाई echoकमांड के लिए हैं /bin/echo, जिनके मैक ओएस पर कोई -eविकल्प नहीं है। जब आप उन सिस्टम पर बैश का उपयोग कर रहे होते हैं, तो इसकी अंतर्निहित echoकमांड खत्म हो जाती है। आप इसे स्पष्ट रूप से टाइप करके /bin/echo whateverऔर व्यवहार में अंतर देखकर देख सकते हैं । अंतर्निहित के लिए प्रलेखन देखने के लिए, टाइप करें help echo
मार्क रीड

1
/bin/echoअक्सर एक OS से दूसरे में और Bash के बिलिन से अलग होता है echo
अगली सूचना तक रोक दिया गया।

@MarkReed: मैं बाद में कोशिश करूँगा, लेकिन जानकारी के लिए धन्यवाद। +1। मैं अपना जवाब यहां छोड़ दूंगा, क्योंकि काफी अच्छी चर्चा चल रही है।
nhahtdh

7
echo -eपोर्टेबल नहीं है - उदाहरण के लिए, इको के कुछ कार्यान्वयन आउटपुट के हिस्से के रूप में "-ई" को प्रिंट करेंगे। यदि आप पोर्टेबिलिटी चाहते हैं, तो इसके बजाय प्रिंटफ का उपयोग करें। उदाहरण के लिए, OS X 10.7.4 पर / bin / echo यह करता है। IIRC बैश बिल्लो इको भी 10.5.0 के तहत अजीब था, लेकिन मुझे विवरण याद नहीं है।
गॉर्डन डेविसन

2
echo -eपहले मुझे काट लिया है ... निश्चित रूप से उपयोग करें printfया catएक हेरेडोक के साथ। <<-यहाँ डॉक्स का वेरिएंट विशेष रूप से अच्छा है क्योंकि आप आउटपुट में इंडेंटेशन का नेतृत्व कर सकते हैं, लेकिन स्क्रिप्ट में पठनीयता के लिए इंडेंट
zbeekman

22

चूंकि मैंने printfएक टिप्पणी में सिफारिश की है, मुझे शायद इसके उपयोग के कुछ उदाहरण देना चाहिए (हालांकि एक उपयोग संदेश को प्रिंट करने के लिए, मैं डेनिस या क्रिस के उत्तरों का उपयोग करने की अधिक संभावना होगी)। printfकी तुलना में उपयोग करने के लिए थोड़ा अधिक जटिल है echo। इसका पहला तर्क एक प्रारूप स्ट्रिंग है, जिसमें हमेशा (जैसे \n) व्याख्या की जाती है; इसमें प्रारूप निर्देश भी शामिल हो सकते हैं , जो इस बात को नियंत्रित करते हैं कि इसमें कोई अतिरिक्त तर्क कहाँ और कैसे शामिल हैं। उपयोग संदेश के लिए इसका उपयोग करने के दो अलग-अलग तरीके हैं:%

सबसे पहले, आप संपूर्ण संदेश को प्रारूप स्ट्रिंग में शामिल कर सकते हैं:

printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: \nup home page: \n"

ध्यान दें कि इसके विपरीत echo, आपको अंतिम नई पंक्ति को स्पष्ट रूप से शामिल करना चाहिए। साथ ही, यदि संदेश में किसी भी %वर्ण को शामिल करने के लिए होता है , तो उन्हें लिखा जाना चाहिए %%। यदि आप बगरेपोर्ट और मुखपृष्ठ पतों को शामिल करना चाहते हैं, तो उन्हें स्वाभाविक रूप से जोड़ा जा सकता है:

printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: %s\nup home page: %s\n" "$bugreport" "$homepage"

दूसरा, आप एक अलग लाइन पर प्रत्येक अतिरिक्त तर्क को प्रिंट करने के लिए प्रारूप स्ट्रिंग का उपयोग कर सकते हैं:

printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: " "up home page: "

इस विकल्प के साथ, बगरेपोर्ट और मुखपृष्ठ पते जोड़ना काफी स्पष्ट है:

printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: $bugreport" "up home page: $homepage"

9

इसके अलावा इंडेंट सोर्स कोड के साथ आप <<-लीडिंग टैब (लेकिन लीडिंग स्पेस नहीं) को इग्नोर करने के लिए (ट्रेलिंग डैश के साथ) इस्तेमाल कर सकते हैं । उदाहरण के लिए यह:

if [ some test ]; then
    cat <<- xx
        line1
        line2
xx
fi

प्रमुख व्हाट्सएप के बिना आउटपुट इंडेंटेड टेक्स्ट:

line1
line2

वह मेरे काम नहीं आया। आप किस खोल का उपयोग कर रहे हैं?
चार ४३

उबंटू में 4.4.19 को टक्कर देने में काम नहीं किया। इसने लाइन 1 और
लाइन

1
@ चार43, आप सही थे। अग्रणी रिक्त स्थान को हटाने के लिए काम नहीं करता है। हालांकि, प्रमुख टैब को हटा देता है। इसलिए मैंने टैब और रिक्त स्थान से, टैब पर और रिक्त स्थान से अपना उत्तर सही किया। गलती के लिये क्षमा करे। मैंने मैनुअल की जाँच की और यह स्पष्ट रूप से कहता है कि टैब हटा दिए गए हैं। इसे मेरे संज्ञान में लाने के लिए धन्यवाद।
अण्डाकार दृश्य

0

यदि आप @ जॉर्ज से समाधान का उपयोग करते हैं और पाते हैं कि सब कुछ एक ही पंक्ति में है, तो सुनिश्चित करें कि आप उद्धरण में चर को संलग्न करें:

echo $__usage

जबकि एक लाइन पर सब कुछ मुद्रित करेगा

echo "$__usage"

newlines को बनाए रखेगा।


यह वास्तव में एक समाधान है जो मेरे लिए काम करता है। Printf बहुत सारी चीजें करता है और मेरी बहु xml के साथ, इसे संभवतः बहुत भागने की आवश्यकता होती है क्योंकि यह पूरी तरह से सामग्री का प्रबंधन करता है। मैं फू = cat <<EOF .... EOF&& गूंज "$ फू" असाइन करता हूं
जिल्स वैन गुरप
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.