हर एन लाइन्स में नईलाइन वर्ण निकालें


16

टेक्स्ट को संसाधित करना, मुझे हर दो लाइनों में नई लाइन वर्ण को निकालने की आवश्यकता है।

नमूना पाठ:

this is line one
and this is line two
the third and the
fourth must be pasted too

वांछित उत्पादन:

this is line one and this is line two
the third and the fourth must be pasted too

मैंने एक whileपाश की कोशिश की , लेकिन थोड़ी देर में पाश बुरा अभ्यास है। क्या इसका उपयोग करना संभव है trया किसी अन्य कमांड का उपयोग करना ?


4
शीर्षक "हर एन लाइनें" कहता है, लेकिन सवाल और उदाहरण में यह "हर 2 लाइनें" है। अधिकांश उत्तर केवल N = 2 के लिए काम करते हैं। क्या आप किसी ऐसी चीज़ की तलाश में हैं जो सभी N के लिए काम करती हो?
जिग्लीगैनागा

यही कुंजी है। हर व्यक्ति ने 2 पंक्तियों के लिए उत्तर दिया लेकिन मुझे N = 3 या N = 4 का उपयोग करने की आवश्यकता होगी
jomaweb

जवाबों:


24

paste(यह भी एक मानक POSIX सरल उपयोगिता की तरह tr) उस के लिए अपने उपकरण है।

यह मानते हुए कि आप चाहते हैं कि उन नएलाइन वर्णों को आपके नमूने के अनुसार हटाए गए स्थान के बजाय बदल दिया जाए :

paste -d ' ' - - < file

या:

paste -sd ' \n' file

प्रतिस्थापित ' 'करें '\0'यदि आप वास्तव में चाहते हैं कि उन्हें हटा दिया जाए।

3 में से 2 को बदलने के लिए:

paste -sd '  \n' file

3 में से 1, दूसरे के साथ शुरू:

paste -sd '\n \n' file

और इसी तरह।

इसके साथ एक और अच्छी बात pasteयह है कि यह एक लाइन को गैर-समाप्त नहीं करेगा। उदाहरण के लिए, यदि आप हर नईलाइन को फ़ाइल में (जैसे tr -d '\n' < fileया साथ tr '\n' ' ' < file) निकालते हैं, तो आप बिना किसी लाइन के समाप्त होते हैं क्योंकि लाइनों को एक नई लाइन वर्ण के साथ समाप्त करने की आवश्यकता होती है। इसलिए यह आम तौर पर pasteइसके बजाय (जैसे paste -sd '\0' fileया paste -sd ' ' file) के लिए उपयोग करना बेहतर होता है जो वैध पाठ के लिए आवश्यक उस अनुगामी न्यूलाइन वर्ण को जोड़ देगा।


11

आधुनिक GNU sed के साथ

sed -rz 's/\n([^\n]*\n)/ \1/g' sample.text

और जाग

awk '{getline line2;print $0, line2}' sample.text

3
उस sedदृष्टिकोण का अर्थ है कि पूरी फ़ाइल को मेमोरी में खिसकाना (बशर्ते उसमें NUL बाइट्स न हों) और कुछ महंगे regexp प्रतिस्थापन करें। मैं मानक sed 'N;s/\n/ /'दृष्टिकोण पर लाभ नहीं देख सकता ।
स्टीफन चेजलस

6

sedनीचे दिखाए अनुसार इसका उपयोग करें :

SHW@SHW:/tmp $ cat a
this is line one
and this is line two
the third and the
fourth must be pasted too

SHW@SHW:/tmp $ sed 'N;s/\n/ /' a -i

SHW@SHW:/tmp $ cat a
this is line one and this is line two
the third and the fourth must be pasted too

4

एक और तरीका है xargs:

$ < txt xargs -d '\n' -n 2 echo
this is line one and this is line two
the third and the fourth must be pasted too

कहाँ पे

$ cat txt
this is line one
and this is line two
the third and the
fourth must be pasted too

हालांकि, यह समाधान काफी अधिक है क्योंकि echoप्रत्येक पंक्ति के लिए एक प्रक्रिया निष्पादित की जाती है ... इस प्रकार, खिलौना उदाहरणों के अलावा, awk / sed या इसी तरह के आधार पर एक समाधान को प्राथमिकता दी जानी चाहिए।


1
आपके echoकार्यान्वयन के आधार पर , आपको बैकलैश पात्रों या कुछ लाइनों के साथ समस्याएँ होंगी जो -( GNU के साथ --helpया जैसे ) से शुरू होती हैं। यह भी ध्यान दें कि एक GNU एक्सटेंशन है। -neneecho-d
स्टीफन चेजलस

मुद्दों से बचने के लिए echo, आप इसका उपयोग कर सकते हैं:< txt xargs -d '\n' -n 2 printf -- '%s %s\n'
nyuszika7h

4

यह वास्तव में बेहद सरल है। प्रत्येक पंक्ति में शामिल होने के लिए Jकमांड का उपयोग करें , फिर %normकमांड का उपयोग करके इसे प्रत्येक पंक्ति में एक साथ लागू करें। उदाहरण के लिए

:%norm J<CR>

(यदि आप विम के साथ अपरिचित हैं, तो <CR>बस प्रवेश का मतलब है)

यह भी लाइनों की एक मनमाना संख्या में शामिल होने के लिए काम करता है। उदाहरण के लिए, हर दस लाइनों में शामिल होने के लिए

:%norm 9J<CR>

यदि आप विम के साथ असहज हैं, और आप इसे इंटरेक्टिव टेक्स्ट एडिटर के बजाय कमांड लाइन टूल के रूप में उपयोग करना पसंद करेंगे, तो आप निम्न कार्य कर सकते हैं:

vim myfile -c '%norm J' -c 'wq'

क्या डाउनवॉटर इस उत्तर को बेहतर बनाने के लिए बता सकता है कि मैं क्या कर सकता हूं?
डीजेएमकेमहेम

3
$ awk '{printf "%s%s",$0,(NR%2?" ":"\n")}' sample.txt
this is line one and this is line two
the third and the fourth must be pasted too

यह प्रत्येक पंक्ति को प्रिंट करता है $0, उसके बाद या तो एक स्थान या एक नई रेखा के आधार पर, चाहे रेखा संख्या NRविषम हो, या विषम हो।

अभिव्यक्ति NR%2?" ":"\n"एक तीखा कथन है। NR%2यदि पंक्ति संख्या विषम है, तो अभिव्यक्ति सही (nonzero) का मूल्यांकन करती है। मामले में, टर्नरी अभिव्यक्ति एक स्थान देता है। यदि यह असत्य (शून्य) का मूल्यांकन करता है, तो नईलाइन वापस आ जाती है।

विकल्प

जैसा कि कॉस्टस द्वारा टिप्पणियों में सुझाया गया है:

$ awk '{ORS=(NR%2?" ":RS)}1' sample.txt
this is line one and this is line two
the third and the fourth must be pasted too

यहां, टर्नेरी स्टेटमेंट NR%2?" ":RSका उपयोग स्पेस या इनपुट रिकॉर्ड सेपरेटर ( RS, डिफ़ॉल्ट = न्यूलाइन) को वापस करने के लिए किया जाता है । यह मान, उत्पादन रिकॉर्ड विभाजक को सौंपा गया है ORS1आदेश के अंत में प्रिंट-रिकार्ड के लिए awk के गुप्त आशुलिपि है।


आप अभी भी 3 वर्णों को बचा सकते हैं: ()कोष्ठक और उसके बाद का स्थान printf;)
अधिकतमशः

1
त्रिगुट? ओह! 'NR%2{printf("%s ",$0);next}1'
कोस्टास

साथ maxschlepzig का जवाब : और त्रिगुट बयान'{ORS=(NR%2?" ":RS)}1'
कोस्टास

@ कोस्टास मुझे पसंद है। उत्तर ORSसमाधान के साथ अद्यतन किया गया ।
जॉन 1024

2

जेनेरिक समाधान, 5आवश्यक लाइनों की संख्या के साथ बदलें

$ # eof to ensure last line has newline ending
$ seq 16 | perl -pe 's/\n/ / if ++$i%5 && !eof'
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16

$ # or just use pr
$ seq 16 | pr -5ats' '
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16

1

आप इसके लिए उपयोग कर सकते हैं awk:

$ awk '{c="\n"} NR%2 {c=" "} { printf("%s%s", $0, c) } ' txt

यह उत्तपन करता है:

this is line one and this is line two
the third and the fourth must be pasted too

कहाँ पे:

$ cat txt
this is line one
and this is line two
the third and the
fourth must be pasted too

awkकार्यों प्रत्येक पंक्ति, विशेष चर के लिए क्रियान्वित कर रहे हैं $0संदर्भ वर्तमान पंक्ति, NRवर्तमान पंक्ति संख्या (1 से शुरु करके) है। दूसरी कार्रवाई अभिव्यक्ति द्वारा पहरा है NR%2, जो मोडुलो ऑपरेशन है। इस प्रकार, c=" "केवल तभी निष्पादित किया NR%2जाता है यदि वह सत्य है, अर्थात विषम रेखा संख्याओं के लिए।

awkवाक्य रचना की तरह सी है, लेकिन कुछ तत्वों कुछ संदर्भों में वैकल्पिक हैं - जैसे अर्धविराम।


आपका cचर है ORS:'NR%2{ORS=" "}1;{ORS=RS}'
कोस्टास

0

का उपयोग कर ed:

$ cat text
this is line one
and this is line two
the third and the
fourth must be pasted too
this is line one
and this is line two
the third and the
fourth must be pasted too

$ ed text <<'END_ED'
g/./s/$/ /\
j
w text.new
END_ED
164
164

$ cat text.new
this is line one and this is line two
the third and the fourth must be pasted too
this is line one and this is line two
the third and the fourth must be pasted too

edसंपादन आदेशों होगा, प्रत्येक पंक्ति के लिए ( gदी नियमित अभिव्यक्ति मिलान हर पंक्ति को आदेश संपादन का एक सेट लागू होता है), समाप्त करने के लिए एक अंतरिक्ष चरित्र जोड़ सकते हैं और अगली पंक्ति के साथ शामिल हो। फिर यह परिणामी पाठ को एक फ़ाइल में लिखता है जिसे कहा जाता है text.new


0

रूबी के साथ।

मुझे लगता है कि nलाइनों के प्रत्येक ब्लॉक में शामिल होना है। मान लीजिए n = 3, इनपुट फ़ाइल है 'infile'और परिणाम फ़ाइल में लिखे जाने हैं 'outfile'

एक फ़ाइल का निर्माण

Ruby -e "File.write 'infile', <<_
> Line 1
> Line 2
> Line 3
> Line 4
> Line 5
> Line 6
> Line 7
> _"

फ़ाइल की सामग्री की पुष्टि करें

ruby -e "p File.read 'infile'"
  # "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\n"

नई प्रतियां निकालें और फाइल करने के लिए लिखें

ruby -e "File.write 'outfile', File.readlines('infile').
  each_with_index { |line,i| line.chomp! unless (i+1)%3==0 }"

सामग्री की पुष्टि करें

ruby -e "puts File.read 'outfile'"
  # ["Line 1", "Line 2", "Line 3\n", "Line 4", "Line 5", "Line 6\n", "Line 7"]

1
अच्छा था। सिद्धांत रूप में, rubyU & L पर ऑफ-टॉपिक है। लेकिन, चूंकि आप इसे कमांड लाइन से उपयोग कर रहे हैं, इसलिए ruby -eयह पर्याप्त विषय पर है।
grochmal
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.