क्या sed नई लाइन वर्णों को प्रतिस्थापित कर सकता है?


42

वहाँ एक मुद्दा है sed और नई लाइन चरित्र के साथ?
मेरे पास निम्नलिखित सामग्रियों के साथ एक फ़ाइल test.txt है

aaaaa  
bbbbb  
ccccc  
ddddd  

निम्नलिखित काम नहीं करता है:
sed -r -i 's/\n/,/g' test.txt

मुझे पता है कि मैं इसके लिए उपयोग कर सकता हूं trलेकिन मेरा सवाल यह है कि यह सेड के साथ क्यों संभव नहीं है।

यदि यह फ़ाइल लाइन को लाइन द्वारा संसाधित करने का एक साइड इफेक्ट है तो मुझे इसमें दिलचस्पी होगी कि ऐसा क्यों होता है। मुझे लगता है कि grepनई लाइनों को हटा देता है। क्या सेड वही करता है?


1
इस मामले में sed का उपयोग करने के लिए सबसे अच्छा उपकरण नहीं हो सकता है (उदाहरण के लिए "tr")। ऐसे उपकरण हैं जो अधिक सहज, पढ़ने / बनाए रखने में आसान, बेहतर प्रदर्शन (विशेष रूप से बड़े डेटा पर) आदि हैं ... अपने शिकंजा का उपयोग करने के लिए स्क्रू का उपयोग न करें (भले ही यह काम करता हो)। आप इस पर एक तुलना पा सकते हैं: http://slash4.de/blog/python/sed-replace-newline-or-python-awk-tr-perl-xargs.html
omoser

2
trएक अनुगामी जोड़ देगा ,और एक निर्विवाद रेखा का उत्पादन करेगा। pasteइसके बजाय सबसे अच्छा उपयोग करना है:paste -sd , test.txt
स्टीफन चेज़लस

जवाबों:


48

GNU के साथ sedऔर प्रदत्त POSIXLY_CORRECTपर्यावरण में नहीं है (सिंगल-लाइन इनपुट के लिए):

sed -i ':a;N;$!ba;s/\n/,/g' test.txt

से https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n :

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

यह इंगित करता है कि समस्या यह है कि sed लाइन द्वारा लाइन पढ़ता है। लेकिन मैं यह नहीं समझ सकता कि यह एक मुद्दा क्यों है। यह सिर्फ लाइन पढ़ सकता है और एक के साथ नई लाइन चरित्र (या अंतिम चरित्र) की जगह ले सकता है,
जिम

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

यह परिणामba: Event not found
krb686

@ krb686 "यह" आप किसका जिक्र कर रहे हैं? क्या आपने sedउन सटीक विकल्पों के साथ उपरोक्त कमांड को चलाया ? किस test.txt फाइल पर? sed(कोशिश sed --version) के किस संस्करण के साथ ?
एंथन

@ एंथन सॉरी, मुझे लगता है कि मुझे "द" कहने का मतलब था। मैंने एक और SO पोस्ट पढ़ी जिसमें मुझे बताया गया कि csh को मुझे भागने की आवश्यकता है !। दिलचस्प बात यह है कि अभी भी मेरे लिए काम नहीं किया और मैंने !अपनी .cshपटकथा में दो बार भागने का काम किया । इसलिए मुझे इस समय वास्तव में कोई समस्या नहीं है, लेकिन क्या आप जानते हैं कि ऐसा क्यों हो सकता है? मेरे लिए क्या काम किया गया थाsed :a;N;$\\!ba;s/\n/ /g'
krb686

17

यह GNU के साथ काम करता है sed:

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

-z 4.2.2 से शामिल है

एनबी। -zचरित्र को शून्य करने के लिए सीमांकक को बदलता है ( \0)। यदि आपके इनपुट में कोई अशक्त अक्षर नहीं है, तो पूरे इनपुट को एक पंक्ति के रूप में माना जाता है। यह अपनी सीमाओं के साथ आ सकता है ।

अंतिम पंक्ति की नई पंक्ति होने से बचने के लिए, आप इसे वापस बदल सकते हैं:

sed -z 's/\n/,/g;s/,$/\n/'

(जो sedफिर से GNU सिंटैक्स है, लेकिन यह पूरी बात नहीं है क्योंकि पूरी बात केवल GNU है)


3
यह अनुगामी न्यूलाइन को भी बदलेगा जो ओपी नहीं चाहता है ... परिणाम की तुलना mikeserv के समाधान से करें।
अप्रैल को don_crissti

7

Oracle की वेब साइट से:

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

मूल रूप से इसका मतलब यह है कि क्योंकि sed लाइन द्वारा लाइन पढ़ रहा है इसलिए न्यूलाइन वर्ण का मिलान नहीं किया गया है।

Https://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n से समाधान है:

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

या, एक पोर्टेबल संस्करण में ( ;जंप मार्क लेबल के बाद समेटे बिना )

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

उस पृष्ठ पर कार्य कैसे प्रदान किया जाता है, इस बारे में स्पष्टीकरण।


मैंने वीपीएन लॉग को पार्स करने के लिए इसके एक संशोधित रूप का उपयोग किया और उपयोगकर्ता को "प्रमाणीकृत" और एक ही लाइन पर टाइम स्टैम्प की जानकारी दी। चीयर्स!
user208145 1

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

5

sedहमेशा \nपैटर्न स्पेस को पॉपुलेट करने से पहले ट्रेलिंग इवलाइन को हटाता है, और फिर इसकी स्क्रिप्ट के परिणामों को लिखने से पहले एक को जोड़ देता है। ई \n-लाइन को विभिन्न माध्यमों से पैटर्न-स्पेस में रखा जा सकता है - लेकिन कभी भी अगर यह एडिट का परिणाम नहीं है। यह महत्वपूर्ण है - पैटर्न की जगह \nमें ewlines sedहमेशा एक परिवर्तन को दर्शाती है, और इनपुट स्ट्रीम में कभी नहीं होती है। \newlines केवल एक सीमांकक हैं जो एक sedडेर अज्ञात इनपुट के साथ भरोसा कर सकते हैं।

यदि आप सभी \newlines को अल्पविराम से बदलना चाहते हैं और आपकी फ़ाइल बहुत बड़ी नहीं है, तो आप ऐसा कर सकते हैं:

sed 'H;1h;$!d;x;y/\n/,/'

यह हर इनपुट लाइन को hपुराने स्पेस में जोड़ देता है - पहले को छोड़कर, जो hपुराने स्पेस को ओवरराइट कर देता है - एक \nईवलाइन कैरेक्टर को फॉलो करते हुए। यह तब उत्पादन से अंतिम dनहीं हर पंक्ति eletes $!। अंतिम पंक्ति पर Hपुराने और पैटर्न रिक्त स्थान e xबदल दिए गए हैं और सभी \newline वर्णों y///को अल्पविराम में अनुवादित किया गया है।

बड़ी फ़ाइलों के लिए इस प्रकार की समस्याएँ पैदा होती हैं - sedलाइन-बाउंड्रीज़ पर बफर, जो इस तरह की क्रियाओं के साथ आसानी से बह सकता है।


2

वैकल्पिक रूप से, आप थोड़ा सरल वाक्यविन्यास का उपयोग कर सकते हैं:

sed ':a;N;s/\n/,/g;ba'

... बस क्रम क्रम बदल रहा है।


3
लेकिन sपैटर्न स्पेस पर प्रत्येक इनपुट लाइन के लिए कमांड चलाता है जो तेजी से बड़ा है।
स्टीफन चेज़लस

1

यहाँ कुछ बहुत अच्छा sed जादू है। और पैटर्न स्पेस ओवरफ्लो के बारे में कुछ अच्छे बिंदु उठाए गए। मुझे सेड का उपयोग करना बहुत पसंद है , जबकि यह सबसे सरल तरीका नहीं है, क्योंकि यह बहुत कॉम्पैक्ट और शक्तिशाली है। हालाँकि इसकी सीमाएँ हैं, और बड़ी मात्रा में डेटा के लिए पैटर्न स्पेस को महाओसिव होना पड़ेगा।

GNU यह कहता है:

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

मेरे पास जोड़ने के लिए बहुत कुछ नहीं है, लेकिन मैं आपको अपने गो-टू की तरफ सेड के लिए गाइड करना चाहूंगा । उत्कृष्ट है। http://www.grymoire.com/Unix/Sed.html

और यहाँ मेरा समाधान है:

for i in $(cat test.txt); do echo -n $i','; done; echo '' >> somewhere

अच्छी तरह से यह काम करता है



-1

मान लीजिए कि आप नई सूचियों को बदलना चाहते हैं \n। मैं ऐसा करना चाहता था, इसलिए यहाँ मैंने क्या किया:

(echo foo; echo bar; echo baz) | sed -r '$!s/$/\\n/' | tr -d '\n' 
# Output: foo\nbar\nbaz

यह है कि यह क्या करता है: अंतिम , अपेंड को छोड़कर सभी लाइनों के लिए \n। फिर, के साथ newlines हटाएँ tr


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