बैश - नई लाइन के साथ अंतरिक्ष की जगह


70

मैं इनपुट पर नई लाइनों के साथ रिक्त स्थान कैसे बदल सकता हूं:

/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5 आदि...

निम्नलिखित प्राप्त करने के लिए:

/path/to/file
/path/to/file2
/path/to/file3
/path/to/file4
/path/to/file5

ध्यान दें

मैं अन्य उपयोगकर्ताओं की मदद करने के लिए यह प्रश्न पोस्ट कर रहा हूं, जब तक मैंने इस प्रश्न को लिखना शुरू नहीं किया, तब तक UNIX SE पर एक उपयोगी उत्तर खोजना आसान नहीं था। उसके बाद मैंने निम्नलिखित पाया:

संबंधित प्रश्न

मैं एक नई लाइन कैसे खोज और बदल सकता हूं?



ls / पथ / को / | xargs गूंज | sed 's / \ s \ + / \ n / g'
एसडी।

जवाबों:


125

trकमांड का उपयोग करें

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5"\
| tr " " "\n"

Http://www.unix.com/shell-programming-scripting/67831-replace-space-new-line.html पर मिला


1
tr मेरा पहला विचार था, हालाँकि इसे करने के बहुत सारे तरीके हैं! यह बहुत अधिक trहै, हालांकि इसके लिए क्या है!
रोब

5
+1, लेकिन एक टिप्पणी के रूप में: यह काम नहीं करता है यदि फ़ाइल नाम में रिक्त स्थान हो
बोन्सी स्कॉट

20

इस स्थिति में मैं प्रिंटफ का उपयोग करूंगा:

printf '%s\n' /path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5

यदि रास्तों में से एक के भीतर रिक्त स्थान हैं, तो आप उस फ़ाइलपथ को उद्धरण दे सकते हैं ताकि इसे रिक्त स्थान पर विभाजित होने से रोका जा सके:

printf '%s\n' /path/to/file '/path/to/file with spaces' /path/to/another/file

सामान्य रूप से पाठ को रूपांतरित करने के लिए, trआपका सबसे अच्छा दांव है, जैसा कि मौजूदा उत्तर में कवर किया गया है।


1
भविष्य से एक त्वरित टिप्पणी: "इको" का उपयोग करने की तुलना में, इस समाधान को पोस्ट करने के लिए धन्यवाद, यह मेरे लिए बहुत विश्वसनीय है।
लाइसेमिथ

5

मान लें कि आपके पास विभाजकों के रूप में रिक्त स्थान है:

newline_separated=${space_separated// /$'\n'}

हालाँकि आप शायद गलत सवाल पूछ रहे हैं। (जरूरी नहीं, उदाहरण के लिए यह एक मेकफाइल में आ सकता है।) फ़ाइल नामों की एक अंतरिक्ष-पृथक सूची वास्तव में काम नहीं करती है: क्या होगा यदि फ़ाइल नामों में से एक में रिक्त स्थान शामिल हैं?

यदि किसी प्रोग्राम को फ़ाइल नाम तर्क के रूप में मिलते हैं, तो उन्हें रिक्त स्थान से न जोड़ें। का प्रयोग करें "$@"एक एक करके उन्हें एक का उपयोग करने की। हालाँकि echo "$@"बीच-बीच में रिक्त स्थान वाले तर्कों को प्रिंट करता है, echoइसके कारण : यह विभाजकों के रूप में रिक्त स्थान के साथ अपने तर्कों को छापता है। somecommand "$@"कमांड के लिए अलग-अलग तर्कों के रूप में फ़ाइल नामों को पास करता है। यदि आप अलग-अलग लाइनों पर तर्क मुद्रित करना चाहते हैं, तो आप उपयोग कर सकते हैं

printf '%s\n' "$@"

यदि आपके पास स्थान-पृथक फ़ाइल नाम हैं और आप उन्हें काम करने के लिए एक सरणी में रखना चाहते हैं, तो आप वर्णों पर मान को विभाजित करने के लिए एक निर्विवाद चर विस्तार का उपयोग कर सकते हैं IFS(आपको वाइल्डकार्ड विस्तार को अक्षम करना होगा set -f, अन्यथा ग्लोब पैटर्न का विस्तार मूल्य में किया जाएगा):

space_separated_list='/path/to/file1 /path/to/file2 /path/to/file3'
IFS=' '; set -f
eval "array=(\$space_separated_list)"
for x in "${array[@]}"; do 

आप इसे ऐसे फ़ंक्शन में एन्क्रिप्ट कर सकते हैं जो -fसेटिंग को पुनर्स्थापित करता है और IFSजब यह किया जाता है तो इसका मूल्य :

split_list () {
  local IFS=' ' flags='+f'
  if [[ $- = *f* ]]; then flags=; fi
  set -f
  eval "$1=($2)"
  set $flags
}
split_list array '/path/to/file1 /path/to/file2 /path/to/file3'
for x in "${array[@]}"; do 

इसका सही उत्तर बदलना। मुझे लगता है कि यह शोध के लिए अधिक सही है कि मुझे अंतरिक्ष-पृथक सूची में कैसे मिला, और उस जानकारी को दूसरे तरीके से पुनः प्राप्त करें। यह मेरे जैसे शिक्षार्थियों के लिए शांत हो सकता है अगर आप थोड़ा अपने snipnet टिप्पणी, हमें क्या स्थानीय वर आईएफएस या हालत $ जैसी चीज़ें कर कह - = है। इस तरह की चीजें जो एक व्यक्ति जो कुछ समय के लिए उपयोग करता है, वह नहीं जानता।
लैकोनाबास

@laconbass मैंने एक छोटा स्पष्टीकरण जोड़ा है। ऊपर देखो set -fऔर IFSपार्टी के मैनुअल में आप सभी विवरण चाहते हैं। यह भी देखें unix.stackexchange.com/questions/16192/…
Gilles

@Guilles वह संक्षिप्त व्याख्या मेरे लिए पर्याप्त है, और मुझे लगता है कि यह कई अन्य लोगों के लिए होगी। अपने समय के लिए Ty
लैकोनबेस

IFSस्थानीय रूप से सेटिंग प्रभावी नहीं होती है
एलिरन मलका

@EliranMalka मुझे इससे कोई मतलब नहीं है कि आपको इससे क्या मतलब है। यदि कोई स्क्रिप्ट उस तरीके का व्यवहार नहीं करती है जो आपको लगता है कि आपको करना चाहिए, तो आप यहां एक प्रश्न पूछ सकते हैं।
गाइल्स

4

व्यावहारिक बनें, sed का उपयोग करें !!

sed 's/\s\+/\n/g' file

ऊपर एक या एक से अधिक व्हाट्सएप अक्षर (\ s +) को न्यूलाइन (\ n) के साथ बदलने के लिए कहते हैं

यह कमोबेश:

'substitute /one space or more/ for /newline/ globally'

1
स्थानापन्न के साथ परिवर्तन को बदलें, यही वास्तव में है!
रोब

@ धन्यवाद, याद रखें कि आप अन्य उत्तरों को संपादित कर सकते हैं।
MGP

1
यदि आपके पास पाठ के बीच कई रिक्त स्थान हैं तो आपको रिक्त लाइनें मिलेंगी। आपको यह इंगित करने के लिए कि आपको एक स्थान के लिए कम से कम एक स्थान से मेल खाना चाहते हैं, के बाद आपको '+' जोड़ने की आवश्यकता है। अर्थात। sed 's / \ s + / \ n / g'
DarkHeart

4

tr@Laconbass से विकल्प के रूप में , आप xargsइस मामले में भी उपयोग कर सकते हैं :

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4  /path/to/file5"\
| xargs -n1

लाभ यह है कि यह कई व्हाट्सएप के साथ भी काम करता है, जो trनहीं करता है।


0

यहाँ देखें कि मैंने यह कैसे किया:

echo "/path/to/file /path/to/file2 /path/to/file3 /path/to/file4 /path/to/file5" | sed 's/ /\
'/g

sedकमांड में बैकस्लैश के बाद एंटर की के उपयोग पर ध्यान दें ।


क्या उच्चारण और विपक्ष sedखत्म हो गया है tr?
लैकोनाबास

आपका कम्फर्ट लेवल :-) मुझे लगता है कि आप अधिक कर सकते हैं sedक्योंकि यह केवल ट्रांसलेट कैरेक्टर्स के बजाय एक एडिटर है।
अनिद्रा

4
sedइतना अधिक कर सकते हैं, लेकिन इस के लिए पूरी तरह से overkill है। trइस काम के लिए सही उपकरण है, लेकिन sedregexes का ज्ञान निश्चित रूप से बाद में काम आएगा!
रोब

0

एक अन्य दृष्टिकोण, यह मानते हुए कि रेखा एक चर में है line:

for path in $line;do echo $path;done

यह इस तथ्य का उपयोग करता है कि बैश डिफ़ॉल्ट रूप से व्हाट्सएप पर अपने तर्कों को विभाजित करता है और यह डिफ़ॉल्ट रूप echoसे अपने इनपुट के लिए एक नई रेखा को जोड़ता है।


इससे पहले कि मैं यह सवाल पोस्ट करता और काम नहीं कर पाता, मैंने अपने ubuntu सिस्टम पर यह कोशिश की।
लैकनबास

0
echo word1 word2 ... | sed -e 'y/ /\n/;P;D'

एकल-अलग-अलग शब्दों को न्यूलाइन में अलग करने के लिए एक और तरीका है।


-1

निम्नलिखित स्क्रिप्ट समझने में आसान है और उपयोग में आसान है।

cat filename | tr ' ' '\n' | tee filename

2
आपके उत्तर का सार ( tr) स्वीकृत उत्तर के समान है। इसके अलावा कि आपके उत्तर में निम्नलिखित समस्याएं हैं: ए) कमांड 4 स्थानों (-> मार्कडाउन लेआउट) के साथ इंडेंट नहीं है। बी) आपका उपयोग catबेकार है (आप इसे बदल सकते हैं < filename tr ' ' '\n')। ग) आपका आउटपुट नाम इनपुट फ़ाइल नाम के समान है। इसके साथ आप एक डेटा रेस बनाते हैं।
maxschlepzig

1
maxschlepzig के सही विश्लेषण के अलावा, यह एक स्क्रिप्ट नहीं है, बल्कि कनेक्टेड कमांड्स का एक समूह है, जिसका नाम हार्डकोड है (जैसा कि स्क्रिप्ट को उम्मीद है कि शेल को निर्दिष्ट करने और उपयोग करने के लिए दो मापदंडों का उपयोग करने और उत्पादन करने के लिए शेल निर्दिष्ट करने वाला हेडर होगा)। इसके अलावा मेरे घर के 3 में से 2 लोगों को समझना आसान नहीं है। हो सकता है कि यह प्रतिनिधि नहीं है, लेकिन ध्यान रखें कि कुछ आप स्वयं समझते हैं (या इस मामले में आपको लगता है कि समझते हैं) हमेशा आसान लगता है।
एंथन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.