इको का उपयोग करते समय नई लाइनें कैसे जोड़ें


42

निम्न कमांड उत्पन्न फ़ाइल में नई लाइनें क्यों नहीं डालती है और इसका क्या समाधान है?

$ echo "Line 1\r\nLine2" >> readme.txt

$ cat readme.txt 
Line 1\r\nLine2

6
है echoअनिवार्य? आप उपयोग कर सकते हैं printf।
— आर्केमर

मैं प्रिंटफ के बारे में नहीं जानता था, प्रिंटफ के साथ यह काम करता है: पी ... तो क्या यह गूंज के साथ काम नहीं करता है?
— Saeid Yazdani

Is \rया की यह की ओर से उत्पादन में शामिल CRLFन्यू लाइन?
— कोउन्ग्लम

9
echoकमांड के कई अलग-अलग कार्यान्वयन एक-दूसरे के साथ असंगत हैं। इस प्रकार यह अधिक मानक उपकरण का उपयोग करने के लिए अनुशंसित है printf। समस्या के विस्तृत अवलोकन के लिए unix.stackexchange.com/questions/65803/… देखें ।
— jimmij

जवाबों:


38

echo


एक echoकार्यान्वयन जो कड़ाई से एकल यूनिक्स विशिष्टता के अनुरूप है यदि आप करते हैं

echo 'line1\nline2'

लेकिन यह एक विश्वसनीय व्यवहार नहीं है। वास्तव में, वास्तव में कोई मानक व्यवहार नहीं है जिसकी आप अपेक्षा कर सकते हैं echo।

ऑपरेंड

string

मानक उत्पादन के लिए लिखी जाने वाली एक स्ट्रिंग। यदि पहला ऑपरेंड है -n, या यदि किसी भी ऑपरेंड में < \backslash> चरित्र है, तो परिणाम कार्यान्वयन-परिभाषित हैं ।

पर XSI-conformant प्रणाली, अगर पहले संकार्य है -n, यह एक स्ट्रिंग, माना जाएगा एक विकल्प नहीं है । निम्नलिखित वर्ण अनुक्रम XSI- अनुरूप प्रणाली में किसी भी तर्क के भीतर पहचाने जाएंगे:

\a- एक <अलर्ट> लिखें ।

\b- एक <backspace> लिखें ।

\c- <newline> को दबाएं जो आउटपुट में अंतिम तर्क का अनुसरण करता है। \cतर्कों में निम्नलिखित सभी पात्रों को अनदेखा किया जाएगा।

\f- एक <form-feed> लिखें ।

\n- एक <newline> लिखें ।

\r- एक <गाड़ी-वापसी> लिखें ।

\t- एक <टैब> लिखें ।

\v- एक <ऊर्ध्वाधर-टैब> लिखें ।

\\- एक <backslash> वर्ण लिखें ।

\0num- एक 8-बिट वैल्यू लिखें जो शून्य, एक, दो या तीन अंकों वाला ऑक्टल नंबर हो num।

और इसलिए वास्तव में यह जानने का कोई सामान्य तरीका नहीं है कि कैसे एक नई पंक्ति के साथ लिखना है echo, सिवाय इसके कि आप आम तौर पर ऐसा echoकरने के लिए बस भरोसा कर सकते हैं ।

एक bashशेल आमतौर पर विनिर्देश के अनुरूप नहीं होता है , और -nऔर अन्य विकल्पों को संभालता है , लेकिन यह भी अनिश्चित है। तुम कर सकते हो:

shopt -s xpg_echo
echo hey\\nthere

hey
there

और यह भी आवश्यक नहीं है किbash बिल्ड-टाइम विकल्प के साथ बनाया गया है ...

--enable-xpg-echo-default

विकल्प की echoआवश्यकता के बिना, अंतर्निहित डिफ़ॉल्ट रूप से अंतर्निहित वर्णों का विस्तार करें -e। यह xpg_echoशेल विकल्प के डिफ़ॉल्ट मान को सेट करता है on, जो बैश echoको एकल यूनिक्स विनिर्देश में निर्दिष्ट संस्करण की तरह अधिक व्यवहार करता है, संस्करण 3. बश बिल्डिंस देखें , जो भागने वाले दृश्यों के विवरण के लिए है echo।


printf


दूसरी ओर, printfव्यवहार बहुत तुलनात्मक है।

औचित्य

printfउपयोगिता कि ऐतिहासिक द्वारा प्रदान की गई है कार्यक्षमता प्रदान करने के लिए जोड़ा गया था echo। हालांकि, अतिरिक्त के विभिन्न संस्करणों में अपूरणीय अंतर के कारण echo, संस्करण में कुछ विशेष विशेषताएं हैं, जो इस नई printfउपयोगिता को छोड़ती हैं , जो कि नौवें संस्करण प्रणाली में एक पर आधारित है।

अतिरिक्त विवरण अनुभाग printf()आईएसओ सी मानक में लगभग फ़ंक्शन से मेल खाता है , हालांकि इसे XBD फ़ाइल स्वरूप संकेतन में फ़ाइल स्वरूप संकेतन के रूप में वर्णित किया गया है ।

यह प्रारूप स्ट्रिंग्स को संभालता है जो इसके तर्कों का वर्णन करता है - जो किसी भी संख्या में हो सकते हैं, लेकिन स्ट्रिंग्स के लिए या तो %bस्ट्रिंग्स या शाब्दिक %sट्रिंग्स बहुत अधिक हैं । %fपहली दलील में ऑर्माट्स से इतर, यह एक %bयेट स्ट्रिंग तर्क की तरह सबसे अधिक व्यवहार करता है, सिवाय इसके कि वह \cभागने से नहीं निपटता ।

printf ^%b%s$ '\n' '\n' '\t' '\t'

^
\n$^    \t$

देखें कि क्यों printfबेहतर है echo? अधिक जानकारी के लिए।


echo() printf


आप अपने खुद के मानकों के अनुरूप लिख सकते echoहैं ...

echo(){
    printf '%b ' "$@\n\c"
}

... जो बहुत ज्यादा हमेशा सही काम करना चाहिए स्वचालित रूप से।

वास्तव में, नहीं ... यह \nतर्क की पूंछ में एक शाब्दिक निशान लगाता है यदि अंतिम तर्क एक विषम संख्या में <backsashes> समाप्त होता है ।

लेकिन यह नहीं है:

echo()
    case    ${IFS- } in
    (\ *)   printf  %b\\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\\n "$*"
            IFS=${IFS#?}
    esac

डिफ़ॉल्ट रूप से उपयोग करने के shopt -s xpg_echoविकल्प के लिए +1 । echo-e
— विग्नेश राजा

इस समाधान के बिना काम नहीं करता है -e। मुझे आश्चर्य है कि किसी ने भी नहीं देखा कि सिवाय शायद @HaydeSchiff
— ha9u63ar

@ ha9u63ar - उह ... क्या आपने इसे पढ़ा?
— mikeserv

27

इस तरह से "\ r \ n" जैसे बच गए पात्रों को पार्स करने के लिए इ-फ्लैग को पास करें, जैसे:

echo -e "Line 1\r\nLine2" >> readme.txt

भागने के क्रम में काम करने के लिए एक अच्छा सरल "-ई" विकल्प - यह एक और उत्तर पर कहता है echoजो अविश्वसनीय है और इसके विपरीत मानकों का पालन नहीं करता है printf।
— एडवर्ड

1
सुनिश्चित करें कि आपकी स्क्रिप्ट में कोई शाब्दिक \ r \ n शामिल नहीं है, जैसे कि tr -d "\n"कमांड में।
— नौमेनन

8

मेरे द्वारा उपयोग किए गए बैश के सभी संस्करणों में, आप बस एक स्ट्रिंग में एक शाब्दिक नई रेखा सम्मिलित कर सकते हैं या तो एक स्क्रिप्ट में या स्क्रिप्ट में, बशर्ते कि स्ट्रिंग पर्याप्त रूप से उद्धृत हो।

सहभागितापूर्ण तरीके:

$ echo "Line one
> Line two"
Line one
Line two
$

एक स्क्रिप्ट में:

echo "Line one
Line two"

4
echo -e "Line 1\r\nLine2" >> readme.txt

आगे उपयोग की संभावनाएं:

man echo

2

लोगों ने पहले से ही पर्याप्त रूप से उत्तर दिया है, लेकिन मैं एक ऐसी दुनिया को स्वीकार करने से इनकार करता हूं जहां गूंज के अलावा किसी भी विकल्प को स्वीकार करता है -n।

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3

1

यदि आपके पास एक ऐसा चरित्र है जो उस संदेश का हिस्सा नहीं है जिसे आप sed के माध्यम से पाइप कर सकते हैं

$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.