मेरे कमांड प्रतिस्थापन से ट्रेलिंग न्यूलाइन चार कहां गया है?


15

निम्न कोड स्थिति का सबसे अच्छा वर्णन करता है। अंतिम पंक्ति अनुगामी न्यूलाइन चार का उत्पादन क्यों नहीं कर रही है? प्रत्येक पंक्ति का आउटपुट टिप्पणी में दिखाया गया है। मैं GNU बैश का उपयोग कर रहा हूँ , संस्करण 4.1.5

     echo -n $'a\nb\n'                  | xxd -p  # 610a620a  
           x=$'a\nb\n'   ; echo -n "$x" | xxd -p  # 610a620a
     echo -ne "a\nb\n"                  | xxd -p  # 610a620a
x="$(echo -ne "a\nb\n")" ; echo -n "$x" | xxd -p  # 610a62

4
जरूरत पड़ने पर दुर्लभ समय के लिए वर्कअराउंड:tmp=$(somecommand; echo a); tmp=${tmp%a}
गिल्स एसओ- बुराई को रोकना '


1
@ गिल्स: ऊपर अपना उदाहरण दें, ऊपर: tmp=$(somecommand; echo a)... इसने निश्चित रूप से पॉइंट होम को संचालित किया है ... जब तक मैंने उदाहरण नहीं देखा, तब तक मेरी प्रवृत्ति अभी भी उपयोग की गई होगी echo -n a... लेकिन, निश्चित रूप से!, कोई ज़रूरत नहीं है! -nक्योंकि कमान प्रतिस्थापन किसी भी मामले में शुरू की अनुगामी न्यू लाइन निकाल देंगे! ... धन्यवाद ...
पीटर।

जवाबों:


18

कमांड प्रतिस्थापन समारोह $()(और इसके चचेरे भाई backtick) विशेष रूप से अनुगामी newlines निकालता है। यह प्रलेखित व्यवहार है , और निर्माण का उपयोग करते समय आपको हमेशा इसके बारे में पता होना चाहिए।

टेक्स्ट बॉडी के अंदर की नई बारीकियों को प्रतिस्थापन संचालक द्वारा हटाया नहीं जाता है, लेकिन शेल पर शब्द विभाजन करते समय उन्हें हटाया भी जा सकता है, इसलिए यह कैसे पता चलता है कि आप उद्धरणों का उपयोग करते हैं या नहीं। इन दो usages के बीच अंतर पर ध्यान दें:

$ echo -n "$(echo -n 'a\nb')"
a
b

$ !! | xxd -p
610a62

$ echo -n  $(echo -n 'a\nb')
a b

$ !! | xxd -p   
612062

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


1
धन्यवाद कालेब .. मुझे शब्द-बंटवारे का पता चल गया था जब व्हाट्सएप को एकल स्थान में बदल दिया गया था ... यही कारण है कि मैं अपनी अनुगामी नईलाइन को गायब होते हुए देखकर सबसे ज्यादा हैरान था, हालांकि मैंने इसे उद्धृत किया था ... अब मुझे पता है कि इसकी वजह यह है कि कमांड
सब्स्टीट्यूशन

6

कमांड प्रतिस्थापन का उपयोग करते समय, शेल एक सबडेल में कमांड निष्पादित करता है, अपने स्टडआउट को वापस करता है। इस प्रक्रिया में, IFS अक्षर अपना महत्व खो देते हैं (यदि उन्हें उद्धृत नहीं किया जाता है), जैसा कि कमेंट सादे विभाजन शब्द देता है, इसलिए अनुगामी हटा दिए जाते हैं। उदाहरण के लिए:

$ echo "$(echo -e '\n')" | wc
 1       0       1

$ echo -e '\n' | wc
2       0       2

और अधिक व्यावहारिक रूप से, pwdतब भी काम करेगा जब आपकी निर्देशिका के नाम के बीच में एक नई रेखा $(pwd)होगी , लेकिन नहीं होगी।

सामान्य वर्कअराउंड अपने कमांड के अंत में कुछ जोड़ना और उसके बाद पट्टी करना है।


1
धन्यवाद फिलोमथ ... वैसे, आप पहला उदाहरण वाक्यात्मक रूप से गलत हैं ('wc' एक स्ट्रिंग को एक arg के रूप में स्वीकार नहीं करता है) .. आप उदाहरण के लिए समझ बनाने के लिए, पहला ऐसा हो सकता है echo "$(echo -e '\n')" | wc, जो आउटपुट 1   0   1की तुलना में हो।2   0   2
पीटर।

@fred: उफ़, बस एक टाइपो।
फिलोमथ

1
"रिक्त स्थान में परिवर्तित" उपयुक्त स्पष्टीकरण नहीं है, इसमें कुछ विभाजन शामिल हैं। विशेष रूप से आप IFS से स्थान निकाल सकते हैं और वे विभाजक के रूप में कार्य नहीं करेंगे। अधिक से अधिक, अपने उदाहरण एक विशेष मामले के श्रेणी में आता है, और वहाँ के बीच एक अंतर है $(pwd)और "$(pwd)"कालेब के जवाब देखें।
स्टीफन जिमेनेज़

PS..सामान्य वर्कअराउंड का आपका सुझाव सिर्फ यही है कि मुझे इसे स्पष्ट करने की आवश्यकता है ..
पीटर।

"रिक्त स्थान में परिवर्तित", वर्ड विभाजन को
पीटर।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.