मैं sed का उपयोग करके एक नई पंक्ति (\ n) को कैसे बदल सकता हूं?


1370

मैं कमांड का उपयोग करके \nएक स्थान (" ") के साथ एक नई पंक्ति (" ") को कैसे बदल सकता हूं sed?

मैंने असफल कोशिश की:

sed 's#\n# #g' file
sed 's#^$# #g' file

मैं इसे कैसे ठीक करूं?


27
trनौकरी के लिए केवल सही उपकरण है यदि किसी एकल चरित्र के लिए एकल वर्ण को प्रतिस्थापित किया जाए, जबकि ऊपर दिया गया उदाहरण दिखाता है कि एक स्थान के साथ नई रेखा को प्रतिस्थापित किया जाता है .. तो उपरोक्त उदाहरण में, tr काम कर सकता है .. लेकिन बाद में सीमित हो जाएगा।
गुस्सा 84

9
trनौकरी के लिए सही टूल क्योंकि प्रश्नकर्ता प्रत्येक नईलाइन को एक स्थान के साथ बदलना चाहता था, जैसा कि उसके उदाहरण में दिखाया गया है। नई सुर्खियों का प्रतिस्थापन विशिष्ट रूप sedसे आसानी से किया जाने वाला आर्कान है tr। यह एक सामान्य प्रश्न है। रेगेक्स रिप्लेसमेंट करना कोई और नहीं trबल्कि sedएक अलग सवाल के लिए सही उपकरण होगा।
माइक एस

3
"tr" भी newline `tr -d '\ n' को हटा सकता है 'हालांकि आप अधिक सार्वभौमिक` tr -d' \ 012 \ 015 '`होने के लिए रिटर्न को हटाना पसंद कर सकते हैं।
एंथनी

2
चेतावनी: "ट्र" लिनक्स और पुराने सोलारिस मशीनों (ईजी सोल 5.8) के बीच एक चरित्र श्रेणियों के संबंध में अलग-अलग कार्य करता है। ईजी: `ट्र-डी 'एज़'` और `ट्र-डी '[एज़]'`। इसके लिए मैं आपको "sed" का उपयोग करने की सलाह देता हूं, जिसमें वह अंतर नहीं है।
एंथनी

2
@ माइक जवाब के लिए धन्यवाद। tr '\012' ' 'एक के साथ पालन ​​करें echo। अन्यथा फ़ाइल में अंतिम लाइनफ़ीड भी हटा दिया जाता है। tr '\012' ' ' < filename; echoउसने चाल चली।
बर्नी रेइटर

जवाबों:


1513

GNU के साथ इस घोल का प्रयोग करें sed:

sed ':a;N;$!ba;s/\n/ /g' file

यह पूरी फाइल को लूप में पढ़ेगा, फिर न्यूलाइन (एस) को एक स्थान के साथ बदल देगा।

स्पष्टीकरण:

  1. के माध्यम से एक लेबल बनाएँ :a
  2. वर्तमान और अगली पंक्ति को पैटर्न स्पेस के माध्यम से जोड़ें N
  3. यदि हम अंतिम पंक्ति से पहले हैं, तो निर्मित लेबल पर शाखा $!ba( $!इसका अर्थ है कि अंतिम पंक्ति पर ऐसा नहीं करना चाहिए क्योंकि एक अंतिम नई पंक्ति होनी चाहिए)।
  4. अंत में प्रतिस्थापन हर न्यूलाइन को पैटर्न स्पेस (जो पूरी फाइल है) पर एक स्थान के साथ बदल देता है।

यहाँ क्रॉस-प्लेटफ़ॉर्म संगत सिंटैक्स है जो बीएसडी और ओएस एक्स के साथ काम करता है sed(जैसा @Benjie टिप्पणी के अनुसार ):

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g' file

जैसा कि आप देख सकते हैं, इसके sedलिए अन्यथा सरल समस्या का उपयोग करना समस्याग्रस्त है। एक सरल और पर्याप्त समाधान के लिए यह उत्तर देखें ।


45
@ अर्जन और मासी: ओएस एक्स sedजीएनयू के बजाय बीएसडी का उपयोग करता है sed, इसलिए दोनों में कुछ सूक्ष्म (और कुछ नहीं तो सूक्ष्म) अंतर हो सकते हैं। यह एक निरंतर दर्द है अगर आप ओएस एक्स और * निक्स दोनों मशीनों पर काम करते हैं। मैं आमतौर पर जीएनयू coreutilsऔर findutilsओएस एक्स पर स्थापित करता हूं , और बीएसडी संस्करणों को अनदेखा करता हूं ।
टेलीमेकस

50
यह :aएक रजिस्टर नहीं है, यह एक शाखा लेबल है। यह bकमांड के लिए एक लक्ष्य है * जो "गोटो" की तरह काम करता है। इसे एक रजिस्टर कहते हुए तात्पर्य है कि आप संग्रहण स्थान बना सकते हैं। केवल दो "रजिस्टर" हैं; एक को "होल्ड स्पेस" कहा जाता है जिसे आपकी स्क्रिप्ट उपयोग नहीं कर रही है और दूसरे को "पैटर्न स्पेस" कहा जाता है। Nआदेश एक नई पंक्ति और और पैटर्न अंतरिक्ष के लिए इनपुट फ़ाइल की अगली रेखा भी संलग्न। [* आपके पास कई लेबल और bकमांड हो सकते हैं । यदि आपके पास एक bलेबल के बिना एक कमांड है, तो इसे अगली पंक्ति और लूप को फिर से पढ़ने के लिए स्क्रिप्ट के अंत में डाल दिया जाता है।]
अगले नोटिस तक रोक दिया गया।

108
आप इस क्रॉस-प्लेटफ़ॉर्म (मैक ओएस एक्स पर) को अर्ध-कॉलोनों के साथ अलग करने के बजाय अलग से कमांड निष्पादित करके चला सकते हैं: sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ /g'
बेन्जी

74
कोई भी इस बात पर टिप्पणी क्यों नहीं कर रहा है कि यह एक गूंगा गड़बड़ है (स्वयं उत्तर नहीं है, लेकिन जिस कार्यक्रम के लिए प्रस्तावित उत्तर एक बहुत ही सरल समस्या का सबसे अच्छा समाधान है)। सिड एक कार की तरह दिखता है जो आमतौर पर ठीक चलता है, लेकिन यदि आप पास की एक विशिष्ट सड़क पर ड्राइव करना चाहते हैं, तो एकमात्र तरीका कार को हेलीकॉप्टर से उठाना है।
अरक-कुन

12
लोगों पर आते हैं - एक पागल, समझ से बाहर समाधान के लिए 261 upvotes जो काम नहीं करता है ???? एक ही लाइन पर साधारण सबसिस्टम के लिए sed एक उत्कृष्ट उपकरण है, कुछ और के लिए बस awk का उपयोग करें। अच्छा दुःख ....
एड मॉर्टन

1711

sedलाइन-आधारित इनपुट पर उपयोग करने का इरादा है। यद्यपि यह वह कर सकता है जिसकी आपको आवश्यकता है।


यहां एक बेहतर विकल्प trनिम्नानुसार कमांड का उपयोग करना है:

tr '\n' ' ' < input_filename

या पूरी तरह से newline वर्ण हटा दें:

tr -d '\n' < input.txt > output.txt

या यदि आपके पास GNU संस्करण है (इसके लंबे विकल्पों के साथ)

tr --delete '\n' < input.txt > output.txt

88
सैड लाइन-आधारित है इसलिए नई कहानियों को समझना मुश्किल है।
अलेक्जेंडर ग्लैडीश

191
sed इनपुट के एक "स्ट्रीम" पर काम करता है, लेकिन यह इसे नईलाइन सीमांकित विखंडू में समझता है। यह एक यूनिक्स उपकरण है, जिसका अर्थ है कि यह एक काम बहुत अच्छी तरह से करता है। एक चीज "एक फ़ाइल लाइन-वार पर काम" है। इसे बनाना कुछ और कठिन होगा, और जोखिम छोटी बात है। कहानी का नैतिक है: सही उपकरण चुनें। आपके बहुत से सवालों के रूप में लगता है कि "मैं इस उपकरण को कैसे बना सकता हूं जो यह करने के लिए कभी नहीं था?" वे सवाल दिलचस्प हैं, लेकिन अगर वे एक वास्तविक समस्या को हल करने के दौरान आते हैं, तो आप शायद गलत कर रहे हैं।
dmckee --- पूर्व-मध्यस्थ बिल्ली का बच्चा

7
@JBBrown trपाइपलाइनों के निर्माण के लिए एक अनदेखी अनदेखी रत्न है।
dmckee --- पूर्व-मध्यस्थ ने बिल्ली का बच्चा

70
tr बहुत अच्छा है, लेकिन आप केवल एकल वर्णों के साथ नई सूची को बदल सकते हैं। यदि आप एक नई सामग्री को स्ट्रिंग के साथ बदलना चाहते हैं, तो आपको एक अलग टूल का उपयोग करने की आवश्यकता है
Eddy

21
@ ईडीआई - मैंने एक पंक्ति के साथ नई लाइनों को बदलने के लिए ट्र का उपयोग किया है जो पाठ में दिखाई नहीं दिया (मैंने बैकटिक का इस्तेमाल किया), फिर बैकटिक को स्ट्रिंग के साथ बदलने के लिए जो मैं उपयोग करना चाहता था
rjohnston

493

तेजी से जवाब

sed ':a;N;$!ba;s/\n/ /g' file
  1. : 'a' लेबल बनाएँ
  2. N अगली पंक्ति को पैटर्न स्पेस में जोड़ता है
  3. $! यदि अंतिम पंक्ति नहीं है , बा शाखा (लेबल) पर जाएँ 'a'
  4. s स्थानापन्न , / \ n / regex नई लाइन के लिए , / / एक स्थान से , / g वैश्विक मेल (जितनी बार हो सके)

चरण 1 से 3 तक लूप लूप होगा जब तक कि यह अंतिम पंक्ति तक नहीं पहुंच जाता है, सभी लाइनें पैटर्न स्पेस में फिट हो जाती हैं जहां sed सभी \ n वर्णों को प्रतिस्थापित करेगा


वैकल्पिक

सभी विकल्प, सेड के विपरीत प्रक्रिया शुरू करने के लिए अंतिम पंक्ति तक पहुंचने की आवश्यकता नहीं होगी

बैश के साथ , धीमी गति से

while read line; do printf "%s" "$line "; done < file

पर्ल के साथ , सेड -जैसी गति

perl -p -e 's/\n/ /' file

tr के साथ , sed की तुलना में तेज़ , केवल एक वर्ण द्वारा प्रतिस्थापित किया जा सकता है

tr '\n' ' ' < file

पेस्ट के साथ , त्रि -प्रकार की गति, केवल एक चरित्र द्वारा प्रतिस्थापित किया जा सकता है

paste -s -d ' ' file

awk के साथ , त्रि -जैसी गति

awk 1 ORS=' ' file

अन्य विकल्प जैसे "इको $ (<फ़ाइल)" धीमा है, केवल छोटी फ़ाइलों पर काम करता है और प्रक्रिया शुरू करने के लिए पूरी फाइल को संसाधित करने की आवश्यकता होती है।


5. अकसर पूछे जाने वाले प्रश्न से लंबा जवाब 5.10

5.10। मैं \ n एस्केप
सीक्वेंस का उपयोग करके एक नई लाइन को मैच या डिलीट क्यों नहीं कर सकता ? मैं \ n का उपयोग करके 2 या अधिक लाइनों का मिलान क्यों नहीं कर सकता?

\ N कभी भी लाइन के अंत में न्यूलाइन से मेल नहीं खाएगा क्योंकि
लाइन को
पैटर्न स्पेस में रखने से पहले न्यूलाइन को हमेशा के लिए हटा दिया जाता है। पैटर्न स्पेस में 2 या अधिक लाइनें प्राप्त करने के लिए,
'N' कमांड या कुछ समान (जैसे 'H; ...; g?') का उपयोग करें।

सैड इस तरह से काम करता है: sed एक बार में एक लाइन पढ़ता है,
समाप्त होने वाली न्यूलाइन को चॉप करता है , पैटर्न स्पेस में जो बचा है उसे डालता है जहां
सेड स्क्रिप्ट इसे संबोधित या बदल सकती है, और जब पैटर्न स्पेस
प्रिंट होता है, तो एक नई लाइन को स्टॉपआउट करने के लिए भेजता है। (या एक फ़ाइल के लिए)। यदि
पैटर्न स्पेस पूरी तरह से या आंशिक रूप से 'd' या 'D' के साथ डिलीट हो जाता है, तो ऐसे मामलों में
नईलाइन नहीं जोड़ी जाती है। इस प्रकार, स्क्रिप्ट की तरह

  sed 's/\n//' file       # to delete newlines from each line             
  sed 's/\n/foo\n/' file  # to add a word to the end of each line         

कभी काम नहीं करेगा, क्योंकि पैटर्न स्पेस में लाइन डालने से पहले ट्रेलिंग न्यूलाइन को हटा
दिया जाता है। उपरोक्त कार्यों को करने के लिए,
इन स्क्रिप्टों में से किसी एक का उपयोग करें:

  tr -d '\n' < file              # use tr to delete newlines              
  sed ':a;N;$!ba;s/\n//g' file   # GNU sed to delete newlines             
  sed 's/$/ foo/' file           # add "foo" to end of each line          

चूंकि GNU सेड के अलावा अन्य सेड के संस्करणों में
पैटर्न बफर के आकार की सीमा होती है , यूनिक्स 'ट्र' उपयोगिता को यहां पसंद किया जाना है।
यदि फ़ाइल की अंतिम पंक्ति में एक नई रेखा होती है, तो GNU sed
आउटपुट में उस नई पंक्ति को जोड़ देगा, लेकिन अन्य सभी को
हटा देगा, जबकि tr सभी newlines को हटा देगा ।

दो या अधिक लाइनों के ब्लॉक का मिलान करने के लिए, 3 मूल विकल्प हैं:
(1) पैटर्न स्थान के लिए अगली पंक्ति को जोड़ने के लिए 'एन' कमांड का उपयोग करें;
(2)
होल्ड लाइन में वर्तमान लाइन को जोड़ने के लिए कम से कम दो बार 'H' कमांड का उपयोग करें , और फिर
x, g, या G के साथ होल्ड स्पेस से लाइनों को पुनः प्राप्त करें ; या (3)
दो निर्दिष्ट पतों के बीच की रेखाओं का मिलान करने के लिए एड्रेस रेंज (सेक्शन 3.3, ऊपर देखें) का उपयोग करें ।

विकल्प (1) और (2) एक \ n पैटर्न स्पेस में
डालेंगे , जहाँ इसे वांछित ('s / ABC \ nXYZ / वर्णमाला / छ') के रूप में संबोधित किया जा सकता है।
लाइनों के एक ब्लॉक को हटाने के लिए 'एन' का उपयोग करने का एक उदाहरण 4.13 खंड में दिखाई देता है
("मैं विशिष्ट लगातार लाइनों के ब्लॉक को कैसे हटा सकता हूं ?")। इस
उदाहरण को डिलीट कमांड को कुछ
और में बदलकर संशोधित किया जा सकता है, जैसे 'पी' (प्रिंट), 'आई' (इंसर्ट), 'सी' (चेंज), 'ए' (अपेंड),
या 'एस' (विकल्प) ।

विकल्प (3) डाल नहीं होगा एक \ पैटर्न अंतरिक्ष में n, लेकिन यह करता है
लगातार लाइनों के एक ब्लॉक से मेल खाते हैं, तो यह हो सकता है कि तुम नहीं
भी जरूरत है \ n क्या आप जो खोज रहे हैं खोजने के लिए। चूंकि GNU sed
संस्करण 3.02.80 अब इस सिंटैक्स का समर्थन करता है:

  sed '/start/,+4d'  # to delete "start" plus the next 4 lines,           

पारंपरिक '/ यहाँ से /, / से वहाँ / {...}' श्रेणी के
पते के अलावा, यह पूरी तरह से \ n के उपयोग से बचने के लिए संभव हो सकता है।


6
trएक महान विचार था, और आपका समग्र कवरेज एक उच्च-गुणवत्ता वाले उत्तर के लिए बनाता है।
न्यू अलेक्जेंड्रिया

1
+1 ( मानक उपयोगिता ) का उपयोग करने के लिए paste... और सभी अन्य!
Totor


4
इस उत्तर के बारे में सबसे अच्छी बात यह है कि "लंबा उत्तर" यह बताता है कि कमांड कैसे और क्यों काम करता है।
pdwalker

3
स्टैकएक्सचेंज पर मैंने जो हजारों उत्तर पढ़े हैं उनमें से यह सबसे अधिक मददगार हो सकता है। मुझे लाइनों में कई वर्णों का मिलान करने की आवश्यकता है। बहु-रेखाओं को कवर करने वाले कोई पिछले सेड के उदाहरण और tr एकाधिक वर्ण मिलान को संभाल नहीं सकते हैं। पर्ल अच्छा लग रहा है, लेकिन मैं उम्मीद के मुताबिक काम नहीं कर रहा हूं। अगर मैं कर सकता हूं तो मैं इस जवाब को कई बार वोट करूंगा।
mightypile

225

एक छोटा जाग विकल्प:

awk 1 ORS=' '

व्याख्या

एक अजीब कार्यक्रम उन नियमों से बना होता है जिनमें सशर्त कोड-ब्लॉक शामिल होते हैं:

condition { code-block }

यदि कोड-ब्लॉक छोड़ा गया है, तो डिफ़ॉल्ट का उपयोग किया जाता है { print $0 }:। इस प्रकार, 1एक वास्तविक स्थिति के रूप में व्याख्या की जाती है और print $0प्रत्येक पंक्ति के लिए निष्पादित की जाती है।

जब awkइनपुट पढ़ता है तो यह रिकॉर्ड्स RS(रिकॉर्ड सेपरेटर) के मूल्य के आधार पर इसे विभाजित करता है , जो डिफ़ॉल्ट रूप से एक नई awkपंक्ति है , इस प्रकार इनपुट लाइन-वार को डिफ़ॉल्ट रूप से पार्स कर देगा। बंटवारे RSमें इनपुट रिकॉर्ड से अलग होना भी शामिल है ।

अब, एक रिकॉर्ड प्रिंट करते समय, ORS(आउटपुट रिकॉर्ड सेपरेटर) को इसमें जोड़ा जाता है, डिफ़ॉल्ट फिर से एक नई पंक्ति है। इसलिए ORSएक स्थान पर बदलकर सभी नए स्थानों को अंतरिक्ष में बदल दिया जाता है।


5
मैं इस सरल समाधान को बहुत पसंद करता हूं, जो दूसरों की तुलना में बहुत अधिक पठनीय है
फेडिर RYKHTIK

8
यदि यह अधिक समझ में आता है, तो यह प्रभावी रूप से लिखा जा सकता है: awk 'BEGIN { ORS=" " } { print $0 } END { print "\n"} ' file.txt(एक नई शुरुआत को जोड़ने के लिए सिर्फ शुरुआत / समाप्ति को दर्शाने के लिए); "1" true(लाइन को प्रोसेस करता है) और print(लाइन प्रिंट करें ) का मूल्यांकन करता है । इस अभिव्यक्ति में एक सशर्त भी जोड़ा जा सकता है, उदाहरण के लिए, केवल एक पैटर्न से मेल खाने वाली लाइनों पर काम करना: awk 'BEGIN { ORS=" " } /pattern/ { print $0 } END { print "\n"} '
michael

2
आप इसे और अधिक कर सकते हैं: codeawk 'ORS = "" file.txtcode
Udi

इस तरह से awk का उपयोग करते समय, दुर्भाग्य से, फ़ाइल में अंतिम पंक्ति फ़ीड को हटा दिया जाता है, भी। पैट्रिक डार्क उत्तर देखें 'tr' का उपयोग करने के बारे में उप-भाग में जैसे 'बिल्ली फ़ाइल | गूंज $ (tr "\ 012" "") `जो चाल करता है। निफ्टी।
बर्न रीटर

143

ग्नू सेड में -zअशक्त अलग रिकॉर्ड (रेखाएं) के लिए एक विकल्प है । आप बस कॉल कर सकते हैं:

sed -z 's/\n/ /g'

4
यहां तक ​​कि अगर इनपुट में नल होते हैं, तो उन्हें संरक्षित किया जाएगा (रिकॉर्ड सीमांकक के रूप में)।
टोबी स्पाईट

6
यदि कोई नल नहीं हैं तो क्या यह पूरे इनपुट को लोड नहीं करेगा? इस मामले में एक बहु-गीगाबाइट फ़ाइल का प्रसंस्करण दुर्घटनाग्रस्त हो सकता है।
रुस्लान

3
@Ruslan, हाँ यह पूरे इनपुट को लोड करता है। यह समाधान बहु-गीगाबाइट फ़ाइलों के लिए एक अच्छा विचार नहीं है।
जेजाओ

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

इसलिए। बहुत। इस।
साजास

85

पर्ल संस्करण जिस तरह से आप उम्मीद काम करता है।

perl -i -p -e 's/\n//' file

जैसा कि टिप्पणियों में बताया गया है, यह ध्यान देने योग्य है कि यह संपादन जगह में है। -i.bakयदि आपकी नियमित अभिव्यक्ति आपके विचार से उतनी स्मार्ट नहीं है , तो प्रतिस्थापन से पहले आपको मूल फ़ाइल का बैकअप देगा ।


23
कृपया कम से कम उल्लेख करें कि -iबिना प्रत्यय के कोई बैकअप नहीं है-i.bakआपको एक आसान, बदसूरत गलती से बचाता है (कहते हैं, टाइप करना -pऔर फ़ाइल को शून्य करना)।
टेलीमेकस

6
@Telemachus: यह एक उचित बिंदु है, लेकिन इसे किसी भी तरह से तर्क दिया जा सकता है। मुख्य कारण जिसका मैंने उल्लेख नहीं किया है, वह यह है कि ओपी के प्रश्न में सेड का उदाहरण बैकअप नहीं बनाता है, इसलिए यह यहाँ बहुत अच्छा लगता है। दूसरा कारण यह है कि मैंने वास्तव में बैकअप कार्यक्षमता का उपयोग नहीं किया है (मुझे लगता है कि स्वचालित बैकअप कष्टप्रद है, वास्तव में), इसलिए मैं हमेशा इसे भूल जाता हूं। तीसरा कारण यह है कि मेरी कमांड लाइन चार वर्णों को लंबा बनाती है। बेहतर या बदतर (शायद बदतर) के लिए, मैं एक अनिवार्य न्यूनतमवादी हूं; मैं सिर्फ संक्षिप्तता पसंद करता हूं। मुझे लगता है कि आप सहमत नहीं हैं। मैं भविष्य में बैकअप के बारे में चेतावनी देने के लिए याद करने की पूरी कोशिश करूंगा।
ire_and_curses 20

6
@Ire_and_curses: वास्तव में, आपने मुझे अनदेखा करने के लिए बहुत अच्छा तर्क दिया है। यही है, आपके पास आपकी पसंद के कारण हैं, और चाहे मैं विकल्पों से सहमत हूं या नहीं, मैं निश्चित रूप से इसका सम्मान करता हूं। मुझे पूरी तरह से यकीन नहीं है कि क्यों, लेकिन मैं इस विशेष बात के बारे में हाल ही में एक आंसू पर रहा हूं ( -iएक प्रत्यय के बिना पर्ल में झंडा)। मुझे यकीन है कि मुझे जल्द ही कुछ और मिल जाएगा। :)
टेलीमेकस

यह वास्तव में दुर्भाग्यपूर्ण है कि यह -फ़ाइल नाम के लिए निर्दिष्ट करके स्टडिन के साथ काम नहीं करता है । क्या ऐसा करने के लिए कोई रास्ता है? यह मेरा तरीका है कि एक फ़ाइल को संशोधित करने के बारे में चिंता न करें, एक पाइपलाइन का उपयोग कर रहा है जो बिल्ली से शुरू होती है।
स्टीवन लू

यदि कोई फ़ाइल नाम नहीं दिया गया है तो @StevenLu पर्ल डिफ़ॉल्ट रूप से STDIN से पढ़ेगा। तो आप कर सकते हैं जैसेperl -i -p -e 's/\n//' < infile > outfile
ire_and_curses

44

किसको चाहिए sed? यहाँ bashतरीका है:

cat test.txt |  while read line; do echo -n "$line "; done

2
अपवोट, मैंने सामान्य रूप से शीर्ष उत्तर का उपयोग किया था, लेकिन जब इसके माध्यम से पाइपिंग / डेव / यूरेनियम, सीड ईओएफ तक प्रिंट नहीं होगा, और ^ सी कोई ईओएफ नहीं है। यह समाधान हर बार एक नई रेखा को देखता है। वास्तव में मुझे क्या चाहिए! धन्यवाद!
वासिली शारापोव

1
तब क्यों नहीं: इको-एन `बिल्ली दिन । 'इस पोस्ट से
टोनी

9
@ क्योंकि बैकस्टिक्स को हटा दिया गया है और बिल्ली बेमानी है;;
seumasmac

10
बिना उपयोग के भी cat : while read line; do echo -n "$line "; done < test.txt। यदि उप-शेल एक समस्या है तो उपयोगी हो सकता है।
कार्लो कान्स

5
echo $(<file)निचोड़ सब एक जगह ही नहीं, नई-पंक्तियों के लिए खाली स्थान के: यह है कि क्या ओ पी पूछ रहा है परे चला जाता है।
ग्लेन जैकमैन

27

पूरी फ़ाइल को मेमोरी में पढ़े बिना, awk का उपयोग करते हुए रिक्त स्थान के साथ सभी नई सूचियों को बदलने के लिए:

awk '{printf "%s ", $0}' inputfile

यदि आप एक अंतिम नई लाइन चाहते हैं:

awk '{printf "%s ", $0} END {printf "\n"}' inputfile

आप अंतरिक्ष के अलावा एक चरित्र का उपयोग कर सकते हैं:

awk '{printf "%s|", $0} END {printf "\n"}' inputfile

END{ print ""}अनुगामी न्यूलाइन के लिए एक छोटा विकल्प है।
इसहाक

22
tr '\n' ' ' 

आज्ञा है।

उपयोग में सरल और आसान।


14
या बस tr -d '\n'अगर आप एक स्पेस नहीं जोड़ना चाहते हैं
spuder

21

तीन चीज़ें।

  1. tr(या cat, आदि) की बिल्कुल जरूरत नहीं है। (GNU) sedऔर (GNU) awkसंयुक्त होने पर, आपके द्वारा आवश्यक किसी भी टेक्स्ट प्रोसेसिंग का 99.9% कर सकते हैं।

  2. स्ट्रीम! = लाइन आधारित। edएक लाइन-आधारित संपादक है। sedनहीं है। अंतर के बारे में अधिक जानकारी के लिए sed व्याख्यान देखें । ज्यादातर लोग sedलाइन-आधारित होने के लिए भ्रमित करते हैं, क्योंकि यह डिफ़ॉल्ट रूप से, इसके पैटर्न में बहुत लालची नहीं है जो कि SIMPLE मैचों के लिए मेल खाता है - उदाहरण के लिए, जब पैटर्न खोज कर रहा है और एक या दो वर्णों की जगह ले रहा है, तो यह डिफ़ॉल्ट रूप से केवल पहले मैच पर बदल देता है यह पाता है (जब तक कि वैश्विक कमांड द्वारा अन्यथा निर्दिष्ट न किया गया हो)। एक वैश्विक कमांड भी नहीं होता अगर यह STREAM- आधारित के बजाय लाइन-आधारित होते, क्योंकि यह एक समय में केवल लाइनों का मूल्यांकन करता था। दौड़ने की कोशिश करो ed; आप अंतर नोटिस करेंगे। edयदि आप विशिष्ट लाइनों (जैसे कि एक लूप में) से अधिक पुनरावृति करना चाहते हैं, तो यह बहुत उपयोगी है, लेकिन अधिकांश समय आप बस चाहते हैं sed

  3. ऐसा कहे जाने के बाद,

    sed -e '{:q;N;s/\n/ /g;t q}' file
    

    GNU sedसंस्करण 4.2.1 में ठीक काम करता है । उपरोक्त कमांड रिक्त स्थान के साथ सभी नई लाइनों को बदल देगा। यह बदसूरत है और टाइप करने के लिए थोड़ा बोझिल है, लेकिन यह ठीक काम करता है। {}के, बाहर छोड़ा जा सकता है के रूप में वे केवल विवेक कारणों के लिए शामिल कर रहे हैं।


3
एक ऐसे व्यक्ति के रूप में जो केवल sedबुनियादी चीजें करना ही जानता है , मेरा कहना है कि यह इस बारे में अधिक है कि आप क्या कर सकते हैं sed, बल्कि यह समझना कितना आसान है कि क्या चल रहा है। मेरे पास काम करने में बहुत कठिन समय है sedइसलिए मैं एक सरल आदेश पसंद करूंगा जब मैं इसका उपयोग कर सकता हूं।
नैट

t qसशर्त कूद के रूप में उपयोग करना यह s/\n / /पूरी फ़ाइल को मेमोरी में पढ़े बिना एक पैटर्न के साथ काम करता है (सभी लाइनों को जोड़ने के लिए जो एक स्थान से शुरू होती है)। बहु मेगाबाइट फ़ाइलों को परिवर्तित करते समय आसान।
श्लोक

आपके द्वारा जोड़ा गया लेख यह नहीं दर्शाता है कि आप क्या कह रहे हैं
hek2mgl

यह बड़े इनपुट पर स्वीकृत उत्तर की तुलना में लगभग 800 गुना धीमा है। यह तेजी से बड़े इनपुट पर हर लाइन के लिए स्थानापन्न होने के कारण है।
थोर

13

के साथ जवाब: एक लेबल ...

मैं sed का उपयोग करके एक नई पंक्ति (\ n) को कैसे बदल सकता हूं?

... कमांड लाइन पर freebsd 7.2 में काम नहीं करता है:

(echo foo; इको बार) | sed ': a; N; $? ba; s / \ n / / g'
sed: 1: ": a; N; $? s; / \ n / / g": अप्रयुक्त लेबल 'एन; एन; $; s / \ n / g'।
foo
बार

लेकिन अगर आप फ़ाइल में sed स्क्रिप्ट डालते हैं या -e का उपयोग करके sed स्क्रिप्ट बनाते हैं ...

> (इको फू; इको बार) | sed -e: a -e N -e '$-ba' -e 's / \ n / / g'
फू बार

या ...

> cat > x.sed << eof
:a
N
$!ba
s/\n/ /g
eof

> (echo foo; echo bar) | sed -f x.sed
foo bar

हो सकता है कि OS X में सेड समान हो।


-ई तर्कों की श्रृंखला ने एमकेएस का उपयोग करके मेरे लिए खिड़कियों पर काम किया! धन्यवाद!
जेम्सगैस

12

आसान समाधान समझने के लिए

मुझे यह समस्या थी। किकर है कि मैं बीएसडी के (मैक ओएस एक्स) और GNU के (लिनक्स और पर काम का हल जरूरी था Cygwin ) sedऔर tr:

$ echo 'foo
bar
baz


foo2
bar2
baz2' \
| tr '\n' '\000' \
| sed 's:\x00\x00.*:\n:g' \
| tr '\000' '\n'

आउटपुट:

foo
bar
baz

(अनुगामी न्यूलाइन है)

यह लिनक्स, ओएस एक्स, और बीएसडी पर काम करता है - यहां तक ​​कि यूटीएफ -8 समर्थन के बिना या एक भद्दा टर्मिनल के साथ।

  1. trकिसी अन्य वर्ण के साथ नई पंक्ति को स्वैप करने के लिए उपयोग करें ।

    NULL( \000या \x00) अच्छा है क्योंकि इसे UTF-8 समर्थन की आवश्यकता नहीं है और इसका उपयोग करने की संभावना नहीं है।

  2. sedमैच के लिए उपयोग करेंNULL

  3. trयदि आपको उनकी आवश्यकता है, तो अतिरिक्त newlines वापस स्वैप करने के लिए उपयोग करें


1
नामकरण पर एक सूक्ष्म नोट: चरित्र \000को आमतौर पर NUL(एक एल) के रूप में संदर्भित किया जाता है , और NULLआमतौर पर शून्य- सूचक (सी / सी ++ में) के बारे में बात करते समय उपयोग किया जाता है ।
sqweek


9

मैं एक विशेषज्ञ नहीं हूं, लेकिन मुझे लगता है कि sedआपको पहली पंक्ति में पैटर्न स्पेस में संलग्न करना होगा, " N" का उपयोग करके बीआईजे । पुस्तक sed & awk (Dale Dougherty and Arnold Robbins; O'Reilly 1997; पूर्वावलोकन में पृष्ठ 107 ) के खंड "मल्टीलाइन पैटर्न स्पेस" से "एडवांस्ड सेड कमांड" में ।

मल्टीलाइन नेक्स्ट (एन) कमांड इनपुट की एक नई लाइन को पढ़कर और इसे पैटर्न स्पेस के कंटेंट में जोड़कर एक मल्टीलाइन पैटर्न स्पेस बनाता है। पैटर्न स्पेस की मूल सामग्री और नई इनपुट लाइन को एक नई रेखा से अलग किया जाता है। एंबेडेड न्यूलाइन कैरेक्टर को एस्केप सीक्वेंस "\ n" द्वारा पैटर्न में मैच किया जा सकता है। मल्टीलाइन पैटर्न स्पेस में, मेटाचेचर "^" पैटर्न स्पेस के पहले वर्ण से मेल खाता है, और किसी भी एम्बेडेड न्यूलाइन (एस) का अनुसरण करते हुए चरित्र (एस) नहीं। इसी तरह, "$" पैटर्न स्पेस में केवल अंतिम न्यूलाइन से मेल खाता है, न कि कोई एम्बेडेड न्यूलाइन (एस)। नेक्स्ट कमांड के निष्पादित होने के बाद, नियंत्रण को स्क्रिप्ट में बाद के कमांड्स में भेज दिया जाता है।

से man sed:

[2addr] एन

मूल सामग्री से संलग्न सामग्री को अलग करने के लिए एक एम्बेडेड न्यूलाइन वर्ण का उपयोग करके, पैटर्न स्पेस के लिए इनपुट की अगली पंक्ति को जोड़ें। ध्यान दें कि वर्तमान लाइन संख्या बदल जाती है।

मैंने इसे (एकाधिक) बुरी तरह से स्वरूपित लॉग फ़ाइलों को खोजने के लिए उपयोग किया है , जिसमें खोज स्ट्रिंग को "अगली पंक्ति" अनाथ पर पाया जा सकता है।


7

मैंने टैब के साथ newlines को बदलने के लिए tr का उपयोग करके न्यूलाइन चीज़ के चारों ओर पाने के लिए एक हाइब्रिड दृष्टिकोण का उपयोग किया, फिर मैं जो कुछ भी चाहता हूं उसके साथ टैब की जगह ले रहा हूं। इस स्थिति में, "
" जब से मैं HTML विराम उत्पन्न करना चाह रहा हूँ।

echo -e "a\nb\nc\n" |tr '\n' '\t' | sed 's/\t/ <br> /g'`

6

विंडोज पर, संभवतः "ट्र" समाधान के जवाब में, प्रस्तावित समाधान के Gnuwin32 संस्करण का उपयोग कर रहा है:

tr '\n' ' ' < input

मेरे लिए काम नहीं कर रहा था, यह या तो त्रुटि करेगा या वास्तव में किसी कारण से \ nw / '' को प्रतिस्थापित करेगा।

Tr की एक अन्य विशेषता का उपयोग करते हुए, "डिलीट" विकल्प -d ने हालांकि काम किया:

tr -d '\n' < input

या '\ n' के बजाय '\ r \ n'


3
विंडोज पर, आपको शायद उपयोग करने की आवश्यकता है tr "\n" " " < input। विंडोज शेल (cmd.exe) एपोस्ट्रोफ को एक उद्धृत चरित्र के रूप में नहीं मानता है।
कीथ थॉम्पसन

नहीं, विंडोज 10 उबंटू सबसिस्टम में, आपको उपयोग करने की आवश्यकता हैtr "\n\r" " " < input.txt > output.txt
user1491819

यह विंडोज 10 पर Gnuwin32 का उपयोग करके काम करता है cat SourceFile.txt | tr --delete '\r\n' > OutputFile.txt:। या, Gnuwin32 के बजाय, Gow (विंडोज पर Gnu), github.com/bmatzelle/gow/wiki
Alchemistmatt

5

बुलेट प्रूफ समाधान। बाइनरी-डेटा-सुरक्षित और पॉसिक्स-अनुपालन, लेकिन धीमा।

POSIX sed को POSIX टेक्स्ट फ़ाइल और POSIX लाइन परिभाषाओं के अनुसार इनपुट की आवश्यकता होती है , इसलिए NULL-बाइट्स और बहुत लंबी लाइनों की अनुमति नहीं है और प्रत्येक पंक्ति को एक नई रेखा (अंतिम पंक्ति सहित) के साथ समाप्त होना चाहिए। इससे मनमाने इनपुट डेटा को संसाधित करने के लिए sed का उपयोग करना कठिन हो जाता है।

निम्न समाधान sed से बचता है और इसके बजाय इनपुट बाइट्स को ऑक्टल कोड में परिवर्तित करता है और फिर फिर से बाइट करता है, लेकिन ऑक्टल कोड 012 (न्यूलाइन) को स्वीकार करता है और इसके स्थान पर प्रतिस्थापन स्ट्रिंग को आउटपुट करता है। जहां तक ​​मैं बता सकता हूं कि समाधान POSIX- अनुरूप है, इसलिए इसे विभिन्न प्रकार के प्लेटफार्मों पर काम करना चाहिए।

od -A n -t o1 -v | tr ' \t' '\n\n' | grep . |
  while read x; do [ "0$x" -eq 012 ] && printf '<br>\n' || printf "\\$x"; done

POSIX संदर्भ दस्तावेज: , शेल कमांड लैंग्वेज , od , tr , grep , रीड , [ , प्रिंटफ

दोनों read, [और printfकम-से-कम बैश में बिल्ट-इन हैं, लेकिन वह शायद POSIX द्वारा गारंटी नहीं है, इसलिए कुछ प्लेटफार्मों पर यह हो सकता है कि प्रत्येक इनपुट बाइट एक या एक से अधिक नई प्रक्रियाएं शुरू करेगा, जो चीजों को धीमा कर देगा। यहां तक ​​कि यह समाधान केवल लगभग 50 kB / s तक पहुंच जाता है, इसलिए यह बड़ी फ़ाइलों के लिए अनुकूल नहीं है।

उबंटू (बैश, डैश और बिजीबॉक्स), फ्रीबीएसडी और ओपनबीएसडी पर परीक्षण किया गया।


5

कुछ स्थितियों में शायद आप RSकिसी अन्य स्ट्रिंग या चरित्र में बदल सकते हैं । इस तरह, उप / gsub के लिए \ n उपलब्ध है:

$ gawk 'BEGIN {RS="dn" } {gsub("\n"," ") ;print $0 }' file

शेल स्क्रिप्टिंग की शक्ति यह है कि यदि आप नहीं जानते कि इसे एक तरीके से कैसे किया जाए तो आप इसे दूसरे तरीके से कर सकते हैं। और कई बार आपके पास एक साधारण समस्या पर एक जटिल समाधान बनाने की तुलना में अधिक चीजें होती हैं।

इस बात के बारे में कि गॉव धीमा है ... और फ़ाइल को मेमोरी में पढ़ता है, मुझे इसकी जानकारी नहीं है, लेकिन मेरे लिए गौक एक समय में एक लाइन के साथ काम करना प्रतीत होता है और बहुत तेज़ है (कुछ लोगों के समान तेज़ नहीं है , लेकिन लिखने और परीक्षण करने का समय भी मायने रखता है)।

मैं एमबी और यहां तक ​​कि जीबी डेटा की प्रक्रिया करता हूं, और मुझे जो एकमात्र सीमा मिली है वह लाइन आकार है।


5

यदि आप विंडोज लाइन के अंत से निपटने के लिए पर्याप्त दुर्भाग्यपूर्ण हैं, तो आपको \rऔर हटाने की आवश्यकता है\n

tr '[\r\n]' ' ' < $input > $output

यह बदल देता है [एक स्थान के साथ, और \rएक स्थान के साथ, और \nएक स्थान के साथ, और ]एक स्थान के साथ। tr -d '\r\n' <fileकिसी भी \rया \nवर्णों को हटा देगा , लेकिन वह भी नहीं है जो पूछा जा रहा है। tr -d '\r' <fileकिसी भी \rवर्ण (चाहे वे आसन्न हों \n) को हटा देंगे जो संभवतः उपयोगी होने के साथ-साथ संभवतः ओपी की आवश्यकता के लिए काफी हद तक सही भी है (फिर भी आपके trइस बैकलेस नोटेशन को समझता है)।
त्रिवेणी

4

आप उपयोग कर सकते हैं xargs- यह \nडिफ़ॉल्ट रूप से एक स्थान के साथ बदल जाएगा ।

हालाँकि, अगर आपके इनपुट में कोई भी मामला है, तो यह समस्या होगी unterminated quote, जैसे यदि किसी दिए गए लाइन पर उद्धरण चिन्ह मेल नहीं खाते हैं।


xargs अंतिम पंक्ति को भी अच्छी तरह से हैंडल करता है:
AAAfarmclub

4

अनुमति देता है और \ n का उपयोग करके प्रतिस्थापित करता है

sed -ie -z 's/Marker\n/# Marker Comment\nMarker\n/g' myfile.txt

निशान

हो जाता है

# मार्कर टिप्पणी

निशान


4

मुझे एक सरल समाधान क्यों नहीं मिला awk?

awk '{printf $0}' file

printf यदि आप मूल लाइनों को किसी स्थान या अन्य के साथ अलग करना चाहते हैं, तो नई लाइनों के बिना हर पंक्ति को प्रिंट करेंगे:

awk '{printf $0 " "}' file

echo "1\n2\n3" | awk '{printf $0}', यह मेरे लिए काम करता है। @ edi9999
इताची

आप सही क्षमा चाहते हैं, मैं f
प्रिंट

यह एकमात्र दृष्टिकोण था जिसने खिड़कियों के लिए गिट बश के भीतर मेरे लिए काम किया
प्लेटो

3

Mac OS X पर (FreeBSD sed का उपयोग करके):

# replace each newline with a space
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g; ta'
printf "a\nb\nc\nd\ne\nf" | sed -E -e :a -e '$!N; s/\n/ /g' -e ta


3

Awk का उपयोग करना:

awk "BEGIN { o=\"\" }  { o=o \" \" \$0 }  END { print o; }"

2
यदि आप बाहरी उद्धरणों को एकल उद्धरण में बदलते हैं, तो आपको उद्धरण चिह्नों और डॉलर चिह्न से बचने की आवश्यकता नहीं है। "ओ" अक्षर को आमतौर पर एक चर नाम के रूप में एक बुरा विकल्प माना जाता है क्योंकि इसे "0" अंक के साथ भ्रमित किया जा सकता है। आपको अपने वैरिएबल को इनिशियलाइज़ करने की भी ज़रूरत नहीं है, यह एक अशक्त स्ट्रिंग को डिफॉल्ट करता है। हालाँकि, यदि आप एक बाहरी अग्रणी स्थान नहीं चाहते हैं awk '{s = s sp $0; sp = " "} END {print s}':। हालाँकि, पूरी फ़ाइल को मेमोरी में पढ़े बिना awk का उपयोग करने के तरीके के लिए मेरा उत्तर देखें।
अगली सूचना तक रोक दिया गया।

कृपया इसके बजाय थोर के जवाब की जाँच करें । यह इस दृष्टिकोण की तुलना करने के लिए हर तरह से अधिक कुशल, पठनीय और बेहतर है (भले ही यह काम करेगा )!
मिस्चिल्ली

यार, मैं समझ गया। इसे मेरे चेहरे पर रगड़ने की आवश्यकता नहीं है :) थोर का उत्तर वैसे भी पृष्ठ पर ऊपर है (जो सही है), तो आपको क्या परवाह है?
क्रालिक

3

एक समाधान जो मुझे विशेष रूप से पसंद है, वह है कि सभी फाइल को होल्ड स्पेस में जोड़ा जाए और फाइल के अंत में सभी न्यूलाइन्स को प्रतिस्थापित किया जाए:

$ (echo foo; echo bar) | sed -n 'H;${x;s/\n//g;p;}'
foobar

हालांकि, किसी ने कहा कि मुझे पकड़ स्थान कुछ sed कार्यान्वयन में परिमित हो सकता है।


1
आपके उत्तर में एक खाली स्ट्रिंग के साथ प्रतिस्थापन इस तथ्य को छिपाता है कि हमेशा होल्ड स्पेस में संलग्न करने के लिए एच का उपयोग करने का मतलब है कि होल्ड स्पेस एक नई रेखा के साथ शुरू होगा। इससे बचने के लिए, आपको उपयोग करने की आवश्यकता है1h;2,$H;${x;s/\n/x/g;p}
जेफ

3

किसी भी स्ट्रिंग के साथ नईलाइन्स बदलें, और अंतिम न्यूलाइन को भी बदलें

शुद्ध trसमाधान केवल एक ही चरित्र के साथ बदल सकते हैं, और शुद्ध sedसमाधान इनपुट के अंतिम न्यूलाइन को प्रतिस्थापित नहीं करते हैं। निम्न समाधान इन समस्याओं को ठीक करता है, और बाइनरी डेटा (यहां तक ​​कि UTF-8 लोकेल के साथ) के लिए सुरक्षित प्रतीत होता है:

printf '1\n2\n3\n' |
  sed 's/%/%p/g;s/@/%a/g' | tr '\n' @ | sed 's/@/<br>/g;s/%a/@/g;s/%p/%/g'

परिणाम:

1<br>2<br>3<br>

यह बुरा है क्योंकि यह किसी भी इनपुट युक्त अवांछित उत्पादन का उत्पादन करेगा@
स्टीवन लू

@StevenLu: नहीं, @इनपुट में ठीक है। यह %aफिर से और वापस भाग जाता है । समाधान पूरी तरह से POSIX अनुरूप नहीं हो सकता है, हालांकि (NULL-बाइट्स ने बाइनरी डेटा के लिए इतना अच्छा नहीं होने दिया और सभी लाइनों को न्यूलाइन के साथ समाप्त होना चाहिए ताकि trआउटपुट वास्तव में मान्य न हो)।
हाकॉन ए। होर्टलैंड

आह। मुझे लगता है कि आपने इसे ठीक कर लिया है। एक साधारण ऑपरेशन होना चाहिए, लेकिन अच्छा काम करने के लिए किंडा को दोषी माना गया।
स्टीवन लू

3

यह वह सेड है जो "सामान्य" प्रतिस्थापन के बाद नई-नई रेखाओं का परिचय देता है। सबसे पहले, यह नई-लाइन चार को ट्रिम करता है, फिर यह आपके निर्देशों के अनुसार प्रक्रिया करता है, फिर यह एक नई-लाइन का परिचय देता है।

Sed का उपयोग करके आप प्रत्येक इनपुट लाइन के लिए, अपनी पसंद की स्ट्रिंग के साथ, छंटनी होने के बाद एक पंक्ति के "अंत" (नई-पंक्ति चार नहीं) को बदल सकते हैं; लेकिन, sed विभिन्न लाइनों का उत्पादन करेगा। उदाहरण के लिए, मान लीजिए कि आप "===" के साथ "लाइन के अंत" को बदलना चाहते थे (एकल स्थान के साथ बदलने की तुलना में अधिक सामान्य):

PROMPT~$ cat <<EOF |sed 's/$/===/g'
first line
second line
3rd line
EOF

first line===
second line===
3rd line===
PROMPT~$

नई-लाइन चार को स्ट्रिंग के साथ बदलने के लिए, आप अक्षम कर सकते हैं, हालांकि, tr का उपयोग करें , जैसा कि पहले बताया गया है, नई लाइन-चार्ट को "विशेष चार" के साथ बदलने के लिए और फिर उस विशेष चार्ट को स्ट्रिंग के साथ बदलने के लिए sed का उपयोग करें जिसे आप चाहते हैं। ।

उदाहरण के लिए:

PROMPT~$ cat <<EOF | tr '\n' $'\x01'|sed -e 's/\x01/===/g'
first line
second line
3rd line
EOF

first line===second line===3rd line===PROMPT~$

3

आप इस विधि का भी उपयोग कर सकते हैं

sed 'x;G;1!h;s/\n/ /g;$!d'

व्याख्या

x   - which is used to exchange the data from both space (pattern and hold).
G   - which is used to append the data from hold space to pattern space.
h   - which is used to copy the pattern space to hold space.
1!h - During first line won't copy pattern space to hold space due to \n is
      available in pattern space.
$!d - Clear the pattern space every time before getting next line until the
      last line.

प्रवाह:
जब पहली पंक्ति इनपुट से प्राप्त होती है, तो विनिमय किया जाता है, इसलिए 1 स्थान को पकड़ने के लिए जाता है और \ n पैटर्न स्पेस में आता है, फिर होल्ड स्पेस को पैटर्न स्पेस में जोड़ा जाता है, और फिर प्रतिस्थापन किया जाता है और पैटर्न स्पेस को हटा दिया जाता है।
दूसरी पंक्ति के आदान-प्रदान के दौरान, 2 स्थान को पकड़ता है और 1 पैटर्न स्थान पर आता है, फिर Gहोल्ड स्पेस को पैटर्न स्पेस में जोड़ें, फिर hपैटर्न को कॉपी करें और प्रतिस्थापन किया जाता है और हटा दिया जाता है। यह ऑपरेशन तब तक जारी रखा जाता है जब तक कि ईओएफ नहीं पहुंच जाता है तब सटीक परिणाम प्रिंट करें।


हालांकि, चेतावनी दी है कि में echo 'Y' | sed 'x;G;1!h;s/\n/X/g;$!d'परिणाम है XY
डरावना

3

एक अन्य GNU sed विधि, लगभग Zsolt Botykai के उत्तर के समान है , लेकिन यह sedकम-अक्सर उपयोग किए जाने वाले y( ट्रांसपेरेट ) कमांड का उपयोग करता है , जो कोड के एक बाइट (अनुगामी g) को बचाता है :

sed ':a;N;$!ba;y/\n/ /'

एक आशा होती y तुलना में तेजी से s(शायद tr20x तेज गति से) चलेगा , लेकिन GNU सेड में v4.2.2 की तुलना में yलगभग 4% धीमा है s


अधिक पोर्टेबल बीएसडी sed संस्करण:

sed -e ':a' -e 'N;$!ba' -e 'y/\n/ /'

2
BSD सेड के साथ yca 15% तेज है। एक कार्यशील उदाहरण के लिए यह उत्तर देखें ।
थोर

इसके अलावा, बीएसडी सेड कमांड के साथ एक लेबल के बाद समाप्त करने की आवश्यकता होती है, इसलिए sed -e ':a' -e 'N;$!ba' -e 'y/\n/ /'जाने का रास्ता होगा।
ghoti
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.