यदि मैं किसी फ़ाइल का अंतिम वर्ण है तो मैं एक नई पंक्ति को कैसे हटा सकता हूं?


162

मेरे पास कुछ फाइलें हैं जिन्हें मैं अंतिम नई पंक्ति को हटाना चाहूंगा यदि यह किसी फ़ाइल का अंतिम चरित्र है। od -cमुझे पता चलता है कि मैं जो कमांड चलाता हूं वह फाइल को एक नई लाइन के साथ लिखता है:

0013600   n   t  >  \n

मैंने sed के साथ कुछ ट्रिक्स आज़माए हैं लेकिन सबसे अच्छा मैं सोच सकता हूँ कि यह ट्रिक नहीं है:

sed -e '$s/\(.*\)\n$/\1/' abc

कोई जानकारी यह कैसे करनी है?


4
newline यूनिक्स newlines के लिए केवल एक चरित्र है। डॉस newlines दो वर्ण हैं। बेशक, शाब्दिक "\ n" दो अक्षर हैं। जो आप वास्तव में देख रहे हैं?
अगली सूचना तक रोक दिया गया।

3
हालांकि प्रतिनिधित्व हो सकता है \n, लिनक्स में एक चरित्र है
पैवियम

10
क्या आप यह जानना चाहते हैं कि आप ऐसा क्यों करना चाहते हैं? जब तक वे पूरी तरह से खाली न हों, तब तक टेक्स्ट फ़ाइलों को अंत-पंक्ति के साथ समाप्त होना चाहिए । यह मेरे लिए अजीब लगता है कि आप ऐसी छंटनी की गई फ़ाइल चाहते हैं?
थॉमस पैड्रॉन-मैक्कार्थी

ऐसा कुछ करने का सामान्य कारण CSV फ़ाइल की अंतिम पंक्ति से एक अनुगामी अल्पविराम को हटाना है। सिड अच्छा काम करता है, लेकिन नई कहानियों को अलग तरह से व्यवहार करना पड़ता है।
पावियम

9
@ थॉमसपैड्रॉन-मैकार्थी "कंप्यूटिंग में, हर अच्छे कारण के लिए कुछ करना है वहाँ एक अच्छा कारण है कि ऐसा न करें और इसके विपरीत।" -जेसस - "आपको ऐसा नहीं करना चाहिए" एक भयानक जवाब है, कोई सवाल नहीं है। सही प्रारूप है: [कैसे करना है] लेकिन [क्यों यह बुरा विचार हो सकता है]। # सैक्रिलेग
कोरी म्हॉटर

जवाबों:


223
perl -pe 'chomp if eof' filename >filename2

या, फ़ाइल को जगह में संपादित करने के लिए:

perl -pi -e 'chomp if eof' filename

[संपादक का नोट: -pi -eमूल रूप से -pie, लेकिन, जैसा कि कई टिप्पणीकारों ने नोट किया था और @hvd द्वारा समझाया गया था, बाद में काम नहीं करता है।]

इसे मैंने देखी गई awk वेबसाइट पर 'perl blasphemy' के रूप में वर्णित किया था।

लेकिन, एक परीक्षण में, इसने काम किया।


11
आप इसे उपयोग करके सुरक्षित बना सकते हैं chomp। और यह फाइल को खिसकाता है।
सिनान Octnür

6
निन्दा हालांकि यह है, यह बहुत अच्छी तरह से काम करता है। perl -i -pe 'chomp अगर eof' फ़ाइल नाम। धन्यवाद।
टोड पार्ट्रिज 'जेन 2' '

13
निन्दा और विधर्म के बारे में मजेदार बात यह है कि यह आमतौर पर नफरत है क्योंकि यह सही है। :)
ईथर

8
छोटा सुधार: आप perl -pi -e 'chomp if eof' filenameएक अस्थायी फ़ाइल बनाने के बजाय किसी फ़ाइल को इन-प्लेस में संपादित करने के लिए उपयोग कर सकते हैं
Romuald Brunet

7
perl -pie 'chomp if eof' filename-> पर्ल स्क्रिप्ट को नहीं खोल सकते हैं "यदि ईओएफ है तो चॉम्प": ऐसी कोई फ़ाइल या निर्देशिका नहीं; perl -pi -e 'chomp if eof' filename-> काम करता है
एडित्सु छोड़ दिया क्योंकि एसई EVIL

56

आप इस तथ्य का लाभ उठा सकते हैं कि शेल कमांड प्रतिस्थापन नई पंक्ति वर्णों को हटाते हैं :

साधारण रूप जो बाश, क्ष, जश में काम करता है:

printf %s "$(< in.txt)" > out.txt

पोर्टेबल (POSIX- आज्ञाकारी) विकल्प (थोड़ा कम कुशल):

printf %s "$(cat in.txt)" > out.txt

ध्यान दें:

  • यदि एकाधिक न्यूलाइन वर्णों के in.txtसाथ समाप्त होता है , तो कमांड प्रतिस्थापन उन सभी को हटा देता है - धन्यवाद, @ श्रावक। (यह newlines अनुगामी के अलावा व्हाट्सएप वर्णों को नहीं हटाता है।)
  • चूंकि यह दृष्टिकोण संपूर्ण इनपुट फ़ाइल को मेमोरी में पढ़ता है , इसलिए यह केवल छोटी फाइलों के लिए ही उचित है।
  • printf %sयह सुनिश्चित करता है कि कोई भी नई आउटपुट आउटपुट से जुड़ी नहीं है (यह गैर-मानक के लिए POSIX- अनुपालन विकल्प है echo -n; http://pubs.opengroup.org/onlinepubs/009696799/utilities/echo.html और https: //unix.stackexchange देखें। कॉम / ए / 65819 )

अन्य उत्तरों के लिए एक गाइड :

  • यदि पर्ल उपलब्ध है, तो स्वीकृत उत्तर के लिए जाएं - यह सरल और मेमोरी-कुशल है (एक बार में पूरी इनपुट फ़ाइल नहीं पढ़ता है)।

  • अन्यथा, पर विचार ghostdog74 के Awk जवाब - यह अस्पष्ट, लेकिन यह भी स्मृति कुशल ; एक अधिक पठनीय समतुल्य (POSIX-compliant) है:

    • awk 'NR > 1 { print prev } { prev=$0 } END { ORS=""; print }' in.txt
    • मुद्रण को एक पंक्ति में देरी हो रही है ताकि अंतिम पंक्ति को ENDब्लॉक में संभाला जा सके , जहां \nआउटपुट-रिकॉर्ड सेपरेटर ( OFS) को खाली स्ट्रिंग पर सेट करने के कारण इसे एक अनुगामी के बिना मुद्रित किया जाता है।
  • यदि आप एक क्रिया चाहते हैं , लेकिन तेज और मजबूत समाधान जो वास्तव में जगह में संपादन करता है (जैसा कि एक अस्थायी बनाने के लिए विरोध किया जाता है। फाइल जो फिर मूल को बदल देती है), तो जॉकवे की पर्ल स्क्रिप्ट पर विचार करें ।


3
NB यदि फ़ाइल के अंत में कई नए समाचार हैं, तो यह कमांड उन सभी को हटा देगा।
स्पार्कहॉक

47

आप इसे headGNU कोरुटिल्स से कर सकते हैं , यह उन तर्कों का समर्थन करता है जो फ़ाइल के अंत के सापेक्ष हैं। इसलिए अंतिम बाइट का उपयोग बंद करने के लिए:

head -c -1

एक अंतिम नईलाइन के लिए परीक्षण करने के लिए जिसका आप उपयोग कर सकते हैं tailऔर wc। निम्न उदाहरण एक अस्थायी फ़ाइल के परिणाम को बचाता है और बाद में मूल को अधिलेखित करता है:

if [[ $(tail -c1 file | wc -l) == 1 ]]; then
  head -c -1 file > file.tmp
  mv file.tmp file
fi

आप "इन-प्लेस" संपादन spongeसे भी उपयोग कर सकते हैं moreutils:

[[ $(tail -c1 file | wc -l) == 1 ]] && head -c -1 file | sponge file

आप इसे अपनी .bashrcफ़ाइल में भरकर एक सामान्य पुन: प्रयोज्य कार्य कर सकते हैं:

# Example:  remove-last-newline < multiline.txt
function remove-last-newline(){
    local file=$(mktemp)
    cat > $file
    if [[ $(tail -c1 $file | wc -l) == 1 ]]; then
        head -c -1 $file > $file.tmp
        mv $file.tmp $file
    fi
    cat $file
}

अपडेट करें

जैसा कि कार्लविल्बर ने टिप्पणियों में उल्लेख किया है और सोरेंटार के उत्तर में उपयोग किया गया है , इन-प्लेस संपादन को truncate --size=-1प्रतिस्थापित head -c-1और समर्थन कर सकता है ।


3
अब तक का सबसे अच्छा समाधान। एक मानक उपकरण का उपयोग करता है जो वास्तव में हर लिनक्स वितरण में है, और संक्षिप्त और स्पष्ट है, बिना किसी सेड या पेर्ल विज़ार्ड के।
डकारन

2
अच्छा समाधान। एक बदलाव यह है कि मुझे लगता है कि मैं truncate --size=-1इसके बजाय इसका उपयोग करूंगा head -c -1क्योंकि यह इनपुट फ़ाइल में पढ़ने के बजाय केवल इनपुट फ़ाइल को आकार देता है, इसे किसी अन्य फ़ाइल पर लिखता है, फिर आउटपुट फ़ाइल के साथ मूल की जगह लेता है।
कार्ल विल्बर

1
ध्यान दें कि head -c -1अंतिम चरित्र को हटा देगा, भले ही यह एक नई पंक्ति हो या न हो, इसीलिए आपको यह जांचना होगा कि क्या अंतिम वर्ण आपके निकालने से पहले एक नई पंक्ति है।
वारबीक्यू

दुर्भाग्य से मैक पर काम नहीं करता है। मुझे संदेह है कि यह किसी भी बीएसडी संस्करण पर काम नहीं करता है।
एडवर्ड फॉक

16
head -n -1 abc > newfile
tail -n 1 abc | tr -d '\n' >> newfile

2 संपादित करें:

यहाँ एक awkसंस्करण (सही किया गया है) जो संभावित रूप से विशाल सरणी को जमा नहीं करता है:

awk '{if (लाइन) प्रिंट लाइन; लाइन = $ 0} END {प्रिंटफ $ 0} 'एबीसी


इसके बारे में सोचने का अच्छा मूल तरीका। धन्यवाद डेनिस।
टोड पार्ट्रिज 'जेन 2' '

तुम सही हो। मैं आपके awkसंस्करण को टालता हूं । यह दो ऑफसेट (और एक अलग परीक्षण) लेता है और मैंने केवल एक का उपयोग किया है। हालाँकि, आप printfइसके बजाय उपयोग कर सकते हैं ORS
अगली सूचना तक रोक दिया गया।

आप आउटपुट को प्रक्रिया प्रतिस्थापन के साथ एक पाइप बना सकते हैं:head -n -1 abc | cat <(tail -n 1 abc | tr -d '\n') | ...
12 को BCoates

2
सिर और पूंछ के लिए -n के बजाय -c का उपयोग और भी तेज होना चाहिए।
रुडाइमियर

1
मेरे लिए, हेड-एन -1 एबीसी ने फ़ाइल की अंतिम वास्तविक रेखा को हटा दिया, जिससे एक अनुगामी न्यूलाइन निकल गई; हेड -c -1 एबीसी बेहतर काम करने के लिए लग रहा था
क्रिस 11

10

gawk

   awk '{q=p;p=$0}NR>1{print q}END{ORS = ""; print p}' file

अभी भी मुझे बहुत सारे किरदार लगते हैं ... इसे धीरे-धीरे सीखना :)। हालांकि काम करता है। आभार भूतडॉग
टॉड पार्ट्रिज 'जेन 2' '

1
awk '{ prev_line = line; line = $0; } NR > 1 { print prev_line; } END { ORS = ""; print line; }' fileइसे पढ़ना आसान होना चाहिए।
येविन पाविलुक

कैसे के बारे में: awk 'NR>1 {print p} {p=$0} END {printf $0}' file
आइजैक

@sorontar प्रारूप तर्क का पहला तर्क printfहै । इस प्रकार यदि इनपुट फ़ाइल में कुछ ऐसा होता है जिसे प्रारूप विशेष के रूप में व्याख्यायित किया जा सकता है , तो आपको एक त्रुटि मिलेगी। इसे ठीक करने के लिए एक बदलाव होगा%dprintf "%s" $0
रॉबिन ए। मीड

9

एकल-लाइन फ़ाइलों के लिए एक बहुत ही सरल विधि, कोरूटिल्स से GNU गूंज की आवश्यकता होती है:

/bin/echo -n $(cat $file)

यह एक सभ्य तरीका है यदि यह बहुत महंगा (दोहरावदार) नहीं है।

यह \nमौजूद है जब मुद्दों है। जैसे-जैसे यह एक नई रेखा में परिवर्तित होता है।
बजे क्रिस स्ट्राइकसिनस्की

यह बहु-पंक्ति फ़ाइलों के लिए भी काम करता है जो $(...)इसे उद्धृत किया गया है
थोर

निश्चित रूप से उद्धृत करने की आवश्यकता है कि ... /bin/echo -n "$(cat infile)" इसके अलावा, मुझे यकीन नहीं है कि अधिकतम लेन echoया शेल ओएस / शेल संस्करणों / डिस्ट्रोस में क्या होगा (मैं सिर्फ इस googling था और यह एक खरगोश छेद था), इसलिए मैं हूं यह निश्चित नहीं है कि यह पोर्टेबल (या प्रदर्शनकारी) वास्तव में छोटी फाइलों के अलावा किसी और चीज के लिए कैसा होगा - लेकिन छोटी फाइलों के लिए, बहुत अच्छा।
माइकल

8

यदि आप इसे सही करना चाहते हैं, तो आपको कुछ इस तरह की आवश्यकता है:

use autodie qw(open sysseek sysread truncate);

my $file = shift;
open my $fh, '+>>', $file;
my $pos = tell $fh;
sysseek $fh, $pos - 1, 0;
sysread $fh, my $buf, 1 or die 'No data to read?';

if($buf eq "\n"){
    truncate $fh, $pos - 1;
}

हम पढ़ने और संलग्न करने के लिए फ़ाइल खोलते हैं; संलग्न करने के लिए खोलने का मतलब है कि हम पहले से ही seekफ़ाइल के अंत में एड हैं । हम तब फ़ाइल के अंत की संख्यात्मक स्थिति प्राप्त करते हैं tell। हम उस संख्या का उपयोग एक वर्ण को वापस लेने के लिए करते हैं, और फिर हम उस एक वर्ण को पढ़ते हैं। यदि यह एक नई रेखा है, तो हम उस नई पंक्ति से पहले फ़ाइल को चरित्र में काट देते हैं, अन्यथा, हम कुछ भी नहीं करते हैं।

यह किसी भी इनपुट के लिए निरंतर समय और निरंतर स्थान में चलता है, और इसके लिए किसी भी अधिक डिस्क स्थान की आवश्यकता नहीं होती है।


2
लेकिन उस फ़ाइल के लिए स्वामित्व / अनुमतियाँ रीसेट नहीं करने का नुकसान है ...
गलत

1
Verbose, लेकिन दोनों तेज और मजबूत - लगता है कि यहाँ केवल सही जगह पर फ़ाइल-संपादन उत्तर है (और चूंकि यह सभी के लिए स्पष्ट नहीं हो सकता है: यह एक पर्ल स्क्रिप्ट है)।
mklement0

6

यहाँ एक अच्छा, साफ सुथरा पायथन समाधान है। मैंने यहां पर कोई प्रयास नहीं किया।

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

यदि अंतिम दो बाइट्स CR / LF हैं, या एक बाइट LF है, तो यह दो बाइट्स द्वारा एक फ़ाइल को काट देता है। यदि अंतिम बाइट (CR) LF नहीं है, तो यह फ़ाइल को संशोधित करने का प्रयास नहीं करता है। यह त्रुटियों को संभालता है। पायथन 2.6 में परीक्षण किया गया।

इसे "स्ट्रिपलास्ट" नामक फ़ाइल में रखें और chmod +x striplast

#!/usr/bin/python

# strip newline from last line of a file


import sys

def trunc(filename, new_len):
    try:
        # open with mode "append" so we have permission to modify
        # cannot open with mode "write" because that clobbers the file!
        f = open(filename, "ab")
        f.truncate(new_len)
        f.close()
    except IOError:
        print "cannot write to file:", filename
        sys.exit(2)

# get input argument
if len(sys.argv) == 2:
    filename = sys.argv[1]
else:
    filename = "--help"  # wrong number of arguments so print help

if filename == "--help" or filename == "-h" or filename == "/?":
    print "Usage: %s <filename>" % sys.argv[0]
    print "Strips a newline off the last line of a file."
    sys.exit(1)


try:
    # must have mode "b" (binary) to allow f.seek() with negative offset
    f = open(filename, "rb")
except IOError:
    print "file does not exist:", filename
    sys.exit(2)


SEEK_EOF = 2
f.seek(-2, SEEK_EOF)  # seek to two bytes before end of file

end_pos = f.tell()

line = f.read()
f.close()

if line.endswith("\r\n"):
    trunc(filename, end_pos)
elif line.endswith("\n"):
    trunc(filename, end_pos + 1)

PS "पर्ल गोल्फ" की भावना में, यहां मेरा सबसे छोटा पायथन समाधान है। यह मेमोरी में मानक इनपुट से पूरी फ़ाइल को स्लैप करता है, अंत में सभी नए सिरे को स्ट्रिप्स करता है, और मानक आउटपुट के लिए परिणाम लिखता है। पर्ल के रूप में नहीं; तुम बस इस तरह थोड़ा मुश्किल तेजी से सामान के लिए पर्ल को हरा नहीं सकते।

कॉल से "\ n" निकालें .rstrip()और यह फ़ाइल के अंत से कई रिक्त लाइनों सहित, सभी सफेद स्थान को छीन लेगा।

इसे "slurp_and_chomp.py" में डालें और फिर चलाएं python slurp_and_chomp.py < inputfile > outputfile

import sys

sys.stdout.write(sys.stdin.read().rstrip("\n"))

os.path.isfile () आपको फ़ाइल उपस्थिति के बारे में बताएगा। कोशिश कर रहा है / छोड़कर विभिन्न त्रुटियों का एक बहुत कुछ पकड़ सकता है :)
डेनिस बर्मनकोव

5

एक तेजी से समाधान ग्नू उपयोगिता का उपयोग कर रहा है truncate:

[ -z $(tail -c1 file) ] && truncate -s-1 file

परीक्षण सही होगा यदि फ़ाइल में एक अनुगामी नई रेखा है।

निष्कासन बहुत तेज़ है, सही मायने में जगह नहीं है, किसी नई फ़ाइल की आवश्यकता नहीं है और खोज भी अंत में केवल एक बाइट ( tail -c1) से पढ़ रही है ।


1
truncate: लापता फ़ाइल ऑपरैंड
ब्रायन हन्ने

2
यह सिर्फ उदाहरण में अनुगामी फ़ाइल नाम को याद कर रहा है, [ -z $(tail -c1 filename) ] && truncate -s -1 filename( यानी, अन्य टिप्पणी के जवाब में, truncateकमांड स्टडिन के साथ काम नहीं करता है, फ़ाइल नाम आवश्यक है)
माइकल

4

अभी तक एक और पर्ल WTDI:

perl -i -p0777we's/\n\z//' filename

3
$ perl -e 'स्थानीय $ /; $ _ = <>; s / \ N $ //; 'a-text-file.txt' प्रिंट करें

यह भी देखें (नई-पंक्तियों सहित) किसी भी चरित्र का मिलान करें sed में


1
जो कि सभी नए किस्से निकालता है। समतुल्यtr -d '\n'
आगे की सूचना तक रोक दिया गया।

यह भी अच्छा काम करता है, शायद paviums की तुलना में कम निन्दा।
टॉड पार्टरिज 'जेन 2 ओली'

सिनान, हालांकि लिनक्स और यूनिक्स एक नई पंक्ति के साथ समाप्त होने के लिए पाठ फ़ाइलों को परिभाषित कर सकते हैं, विंडोज ऐसी कोई आवश्यकता नहीं है। उदाहरण के लिए, नोटपैड, केवल उन वर्णों को लिखेगा जिन्हें आप अंत में कुछ भी अतिरिक्त जोड़कर लिखते हैं। सी कंपाइलरों को लाइन ब्रेक के साथ समाप्त होने के लिए एक स्रोत फ़ाइल की आवश्यकता हो सकती है, लेकिन सी स्रोत फाइलें "सिर्फ" पाठ फाइलें नहीं हैं, इसलिए उनकी अतिरिक्त आवश्यकताएं हो सकती हैं।
राब केनेडी

उस नस में, अधिकांश जावास्क्रिप्ट / सीएसएस मिनिफ़र नई अनुगामी को हटा देंगे, और फिर भी पाठ फ़ाइलों का उत्पादन करेंगे।
4

@ रोब कैनेडी और @ सिस्ट: वहाँ एक दिलचस्प तर्क है कि इस तरह की फाइलें वास्तव में टेक्स्ट फाइलें और ऐसी क्यों नहीं हैं।
सिनान Novnür

2

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

file='/path/to/file'
[[ "$(tail -c 1 "${file}" | tr -dc '\n' | wc -c)" -eq 1 ]] && \
    printf "" | dd  of="${file}" seek=$(($(stat -f "%z" "${file}") - 1)) bs=1 count=1
    #printf "" | dd  of="${file}" seek=$(($(wc -c < "${file}") - 1)) bs=1 count=1

2
perl -pi -e 's/\n$// if(eof)' your_file

प्रभावी रूप से स्वीकृत उत्तर के समान, लेकिन गैर-पर्ल उपयोगकर्ताओं के लिए अवधारणा में स्पष्ट रूप से स्पष्ट है। नोट के लिए कोई आवश्यकता नहीं है कि gया कोष्ठकों के आसपास eof: perl -pi -e 's/\n$// if eof' your_file
mklement0

2

यूनिक्स फ़ाइल प्रकार को मानते हुए और आप केवल यह चाहते हैं कि अंतिम नई पंक्ति इस काम करे।

sed -e '${/^$/d}'

यह कई newlines पर काम नहीं करेगा ...

* काम करता है केवल अगर अंतिम पंक्ति एक खाली लाइन है।


यहाँ एक sedसमाधान है जो एक गैर-रिक्त अंतिम पंक्ति के लिए भी काम करता है: stackoverflow.com/a/52047796
wisbucky

1

फिर भी एक और जवाब एफटीआर (और मेरा पसंदीदा!): इको / कैट को जिस चीज को आप स्ट्रिप करना चाहते हैं और बैकटिक्स के माध्यम से आउटपुट कैप्चर करना चाहते हैं। अंतिम नई लाइन छीन ली जाएगी। उदाहरण के लिए:

# Sadly, outputs newline, and we have to feed the newline to sed to be portable
echo thingy | sed -e 's/thing/sill/'

# No newline! Happy.
out=`echo thingy | sed -e 's/thing/sill/'`
printf %s "$out"

# Similarly for files:
file=`cat file_ending_in_newline`
printf %s "$file" > file_no_newline

1
मुझे दुर्घटना से कैट-प्रिंटो कॉम्बो मिला (विपरीत व्यवहार प्राप्त करने की कोशिश कर रहा था)। ध्यान दें कि यह केवल पिछले नहीं, बल्कि सभी अनुगामी नए समाचारों को निकाल देगा ।
टेक्नोसॉरस

1

POSIX SED:

'$ {/ ^ $ / घ}'

$ - match last line


{ COMMANDS } - A group of commands may be enclosed between { and } characters. This is particularly useful when you want a group of commands to be triggered by a single address (or address-range) match.

मुझे लगता है कि यह केवल इसे हटा देगा यदि अंतिम पंक्ति रिक्त है। यदि अंतिम पंक्ति रिक्त नहीं है, तो यह अनुगामी नई पंक्ति को नहीं हटाएगा। उदाहरण के लिए, echo -en 'a\nb\n' | sed '${/^$/d}'कुछ भी नहीं हटाएगा। echo -en 'a\nb\n\n' | sed '${/^$/d}'पूरी अंतिम पंक्ति के खाली होने के बाद हटा देगा।
बुद्धिमत्तापूर्ण

1

यह एक अच्छा समाधान है यदि आपको इसे पढ़ने या आउटपुट से या किसी फ़ाइल के बजाय पाइप / पुनर्निर्देशन के साथ काम करने की आवश्यकता है। यह सिंगल या मल्टीपल लाइनों के साथ काम करता है। यह काम करता है कि एक अनुगामी newline है या नहीं।

# with trailing newline
echo -en 'foo\nbar\n' | sed '$s/$//' | head -c -1

# still works without trailing newline
echo -en 'foo\nbar' | sed '$s/$//' | head -c -1

# read from a file
sed '$s/$//' myfile.txt | head -c -1

विवरण:

  • head -c -1स्ट्रिंग के अंतिम चरित्र को काटता है, चाहे चरित्र कोई भी हो। इसलिए यदि स्ट्रिंग एक नई रेखा के साथ समाप्त नहीं होती है, तो आप एक चरित्र खो देंगे।
  • तो उस समस्या को दूर करने के लिए, हम एक और कमांड जोड़ते हैं जो एक अनुगामी न्यूलाइन जोड़ देगा यदि एक नहीं है sed '$s/$//':। पहला $साधन केवल कमांड को अंतिम पंक्ति में लागू करता है। s/$//का अर्थ है "लाइन का अंत" "कुछ भी नहीं" के साथ, जो मूल रूप से कुछ नहीं कर रहा है। लेकिन यह एक अनुगामी newline जोड़ने का एक साइड इफेक्ट है वहाँ एक नहीं है।

नोट: मैक का डिफ़ॉल्ट विकल्प का headसमर्थन नहीं करता -cहै। आप इसके बजाय कर सकते हैं brew install coreutilsऔर उपयोग कर सकते हैं ghead


0

केवल एक बार जब मैं ऐसा करना चाहता था, कोड गोल्फ के लिए है, और फिर मैंने अभी-अभी अपने कोड को फ़ाइल से कॉपी किया है और इसे एक echo -n 'content'>fileस्टेटमेंट में पेस्ट किया है ।


आधे रास्ते वहाँ; पूर्ण दृष्टिकोण यहाँ
mklement0

0
sed ':a;/^\n*$/{$d;N;};/\n$/ba' file

काम करता है, लेकिन सभी नई अनुगामी को निकालता है।
mklement0

0

मुझे एक समान समस्या थी, लेकिन एक विंडोज़ फ़ाइल के साथ काम कर रहा था और उन CRLF को रखने की आवश्यकता थी - लिनक्स पर मेरा समाधान:

sed 's/\r//g' orig | awk '{if (NR>1) printf("\r\n"); printf("%s",$0)}' > tweaked

0
sed -n "1 x;1 !H
$ {x;s/\n*$//p;}
" YourFile

फ़ाइल में किसी भी अंतिम घटना को दूर करना चाहिए। विशाल फ़ाइल पर काम नहीं कर रहा है (सीड बफर सीमा के कारण)


0

माणिक:

ruby -ne 'print $stdin.eof ? $_.strip : $_'

या:

ruby -ane 'q=p;p=$_;puts q if $.>1;END{print p.strip!}'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.