बैश चर में नई लाइन


9

मैं कई लाइनों को बैश वैरिएबल में स्टोर करने की कोशिश कर रहा हूं, लेकिन यह काम नहीं करता है।

उदाहरण के लिए, यदि मैं /binप्रति पंक्ति एक फ़ाइल सूचीबद्ध करता हूं और उसे संग्रहीत करता $LSहूं, तो मैं $LSस्टडिन के रूप में पास करता हूं wc, यह हमेशा 1 रिटर्न देता है:

$ ls -1 /bin | wc -l
134
$ LS=$(ls -1 /bin); wc -l <<< $LS
1

अगर मैं स्क्रीन पर आउटपुट देने की कोशिश करता हूं, तो मुझे कई परिणाम मिलते हैं: echoसभी लाइनों को एक ही लाइन पर printfप्रिंट करता है , जबकि केवल पहली लाइन को प्रिंट करता है:

#!/bin/bash
LS=$(ls -1 /bin)
echo $LS
printf $LS

तो, एक बैश वैरिएबल में कई लाइनें हो सकती हैं?

जवाबों:


15

आपको इसे दोगुना करने की आवश्यकता है (और आपको अधिकतर मामले में दोहरे उद्धरण चर चाहिए ):

echo "$LS"

लेकिन गूंज का उपयोग नहीं करते चर सामग्री मुद्रित करने के लिए, का उपयोग कर के बजाय printf :

printf '%s\n' "$LS"

1
बस समग्र जवाब पर एक महीन बिंदु डालने के लिए: प्रिंटफ एक प्रारूप स्ट्रिंग को इसका पहला पैरामीटर होने की उम्मीद करता है, यही वजह है कि उन्होंने वह नहीं देखा जो वे उम्मीद करते थे। अगर वे प्रिंटफ से आउटपुट में नई-नई ख्वाहिशें देखना चाहते हैं, printf "%s\n" $LSतो स्पेस पर अलग-अलग बंटवारा करेंगे।
जेफ स्कालर

% रास, $ रास होना चाहिए btw (मैं इस तरह के एक छोटे से संपादित नहीं कर सके)
जेफ स्कालर

धन्यवाद! यह निश्चित रूप से wcऔर अन्य आदेशों के साथ भी काम करता है :wc -l <<< "$LS"
जादूगर79

1
@JeffSchaller: नहीं, आपको इस मामले में वैरिएबल को नहीं हटाना चाहिए, यदि आप नईलाइन printf '%s\n' "$LS"देखना चाहते हैं तो इसका उपयोग करें । यह गलत टाइपिंग है, इसे ठीक किया!
कोउंगलम

आपको चर मुद्रित करने के लिए इको का उपयोग क्यों नहीं करना चाहिए?
123

9

नए संस्करण चर में हैं। के आउटपुट के LS=$(ls -1)लिए चर सेट करता है (जो उसी तरह का आउटपुट उत्पन्न करता है, जिस तरह से, जब आउटपुट किसी टर्मिनल पर जाता है) को छोड़कर, शून्य से अनुगामी।LSls -1ls

समस्या यह है कि जब आप मूल्य का प्रिंट निकालते हैं तो आप नई कड़ियों को हटा देते हैं। शेल स्क्रिप्ट में, $LS"वैरिएबल का मान" नहीं है LS, इसका मतलब है "मान लें LS, इसे शब्दों में विभाजित करें IFSऔर प्रत्येक शब्द को एक ग्लोब पैटर्न के रूप में व्याख्या करें"। का मान प्राप्त करने के लिए LS, आप लिखने की जरूरत है "$LS"और आम तौर पर डाल करने के लिए, या $LSदोहरे उद्धरण चिह्नों के बीच।

echo "$LS"के मूल्य को प्रिंट करता है LS, कुछ गोले को छोड़कर जो बैकस्लैश वर्णों की व्याख्या करता है, और कुछ मूल्यों को छोड़कर जो इसके साथ शुरू होते हैं -

printf "$LS"LSजब तक इसका कोई प्रतिशत या बैकलैश कैरेक्टर नहीं होता है, तब तक वैल्यू प्रिंट करता है और (ज्यादातर इम्प्लीमेंटेशन के साथ) शुरू नहीं होता है -

LSवास्तव में मूल्य प्रिंट करने के लिए , का उपयोग करें printf %s "$LS"। यदि आप अंत में एक नई रूपरेखा चाहते हैं, तो उपयोग करें printf '%s\n' "$LS"

ध्यान दें कि $(ls)सामान्य रूप से, वर्तमान निर्देशिका में फ़ाइलों की सूची नहीं है। यह केवल तब काम करता है जब आपके पास पर्याप्त रूप से फ़ाइल नाम हैं। फ़ाइल नामों की सूची प्राप्त करने के लिए (डॉट फ़ाइलों को छोड़कर), आपको वाइल्डकार्ड का उपयोग करने की आवश्यकता है *:। परिणाम स्ट्रिंग की एक सूची है, न कि एक स्ट्रिंग, इसलिए आप इसे स्ट्रिंग चर को निर्दिष्ट नहीं कर सकते हैं; आप files=(*)गोले में एक सरणी चर का उपयोग कर सकते हैं जो उनका समर्थन करता है (ksh93, bash, zsh)।

अधिक जानकारी के लिए, देखें कि मेरी शेल स्क्रिप्ट व्हॉट्सएप या अन्य विशेष पात्रों पर क्यों चोक करती है?


प्रिंटफ "$ LS" भी बैकस्लैश कैरेक्टर पार्सिंग के
आगे झुक जाएगा

0

पूर्वकथित

printf '%s\n' "$LS"

एकमात्र सही समाधान है।

मुझे प्रदर्शित करें कि अन्य प्रस्तावित समाधान, दोनों के साथ echoऔर printf, बस ठीक से काम नहीं करते हैं:

$ mkdir t
$ cd t
$ touch \\n
$ LS=$(ls -l)
$ echo "$LS"
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12

$ printf "$LS\n"
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12

$ printf '%s\n' "$LS"
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12 \n
$ ls -l
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12 \n
$ rm \\n
$ cd ..
$ rmdir t
$

(एक के साथ भी परीक्षण कर सकते हैं V=$(printf 'line0:\\n\\n\nline1.\n') printf '%s\n' "$V"और रूपांतर।)

जबकि \nफ़ाइल नाम में वह सामान्य नहीं हो सकता है, git diffएक चर में स्टोर हो सकता है , और शाब्दिक मुठभेड़ की आपकी संभावना \nनाटकीय रूप से बढ़ जाती है।


ध्यान दें कि kshऔर zshभी समर्थन print -r -- "$LS"और zshभी है echo -E - $LScshहै echo $LS:qअगर $ रास खाली है, और पहली जगह में $ लोकसभा में एक बहु मूल्य हो रही csh में काफी मुश्किल है कि हालांकि नहीं उत्पादन न्यू लाइन चरित्र करता है।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.