2013-05-03 16 views
14

Entfernen aller Zeilenumbrüche entfernen könnte man sagen:ein Newline-Zeichen am Ende einer Datei

tr -d '\n' < days.txt 
cat days.txt | tr -d '\n' 

aber wie würden Sie tr benutzen Sie einfach die Newline am Ende/Ende einer Textdatei zu entfernen?

Ich bin nicht sicher, nur die letzte zu spezifizieren.

+0

möglich Duplikat (http [Wie ich eine neue Zeile löschen kann, wenn es das letzte Zeichen in einer Datei ist?]: // Stackoverflow.com/questions/1654021/how-can-i-löschen-ein-newline-wenn-es-ist-das-letzte-zeichen-in-einer-datei) –

Antwort

16

Nutzen Sie die Tatsache, dass a) die Neue-Zeile-Zeichen am Ende der Datei ist, und b) das Zeichen ist 1 Byte groß: Verwenden Sie die truncate Befehl, die Datei durch ein Byte zu schrumpfen:

# a file with the word "test" in it, with a newline at the end (5 characters total) 
$ cat foo 
test 

# a hex dump of foo shows the '\n' at the end (0a) 
$ xxd -p foo 
746573740a 

# and `stat` tells us the size of the file: 5 bytes (one for each character) 
$ stat -c '%s' foo 
5 

# so we can use `truncate` to set the file size to 4 bytes instead 
$ truncate -s 4 foo 

# which will remove the newline at the end 
$ xxd -p foo 
74657374 
$ cat foo 
test$ 

Sie können auch die Dimensionierung und Mathematik in einen einzeiligen Befehl rollen:

truncate -s $(($(stat -c '%s' foo)-1)) foo 
+23

Sie können einfach 'truncate -s -1' verwenden und es wird die Mathematik für Sie tun .. –

+0

@MarkReed Antwort ist die einfachste. –

+0

Einfachere Lösungen unten! –

10

Ich denke, Ihre beste Wette ist, Perl:

perl -0pe 's/\n\Z//' days.txt 

Die -0 Ursachen die gesamte Datei als eine große Zeichenfolge zu behandeln Perl. Die -p sagt ihm, diese Zeichenfolge wieder nach dem Ausführen des Programms darauf zu drucken. Und die -e sagt "hier ist das Programm zu laufen".

Der reguläre Ausdruck \n\Z entspricht einer neuen Zeile, aber nur, wenn es das letzte Zeichen in dieser Zeichenfolge ist. Und s/\n\Z// sagt, eine solche Newline durch nichts zu ersetzen, löschen Sie es.

Der obige Befehl gibt die neue Version der Datei aus, Sie können jedoch die vorhandene ändern, indem Sie die Option -i ("in-place") hinzufügen, optional mit einem Suffix, das zum Benennen einer Sicherungskopie verwendet wird die Datei, bevor es zu ändern:

perl -i.bak -0pe 's/\n\Z//' days.txt 

Diese Lösung ist sicher, dass, wenn das letzte Zeichen nicht ein newline, wird es nicht berührt werden. Die anderen Lösungen, die einfach das letzte Byte entfernen, egal was eine solche Datei beschädigt.

+0

Schöne Möglichkeit, es mit Perl zu tun – tonix

+0

Dies funktioniert auf macOS als naja, außer 'trunkate' oder' head -c -1'. – codeforester

4

diesen Befehl versuchen: sed '$ { /^$/ d}' days.txt

Sie können es lesen als: "Überprüfen Sie, ob die letzte Zeile eine leere Zeile ist. Wenn ja, lösche diese Zeile ". Ich habe mit beiden Fällen getestet: zuerst mit einer Datei mit einer neuen Zeile am Ende und ein anderes Mal mit einer Dateiendung mit etwas anderem.

+1

Noch besser mit 'sed's In-Place-Modus: sed -i '$ {/^$/d}' days.txt – DreamFlasher

18

Wenn Sie sicher sind, dass das letzte Zeichen ein ist new-line, ist es sehr einfach:

head -c -1 days.txt 

head -c -N bedeutet alles mit Ausnahme der letzten N Bytes

+7

habe' head: illegale Byte-Zählung - -1' auf OS X Yosemite 10.10.5 :( – talles

+0

selbe auf MacOS High Sierra 10.13. 'Illegale byte count' –

+0

Für MacOS müssen Sie" brew install coreutils "erstellen und' ghead' verwenden. – dev

21

eine einfachere Lösung als die akzeptiert ein:

truncate -s -1 <<file>> 

Vom truncate Manpage:

-s, --size=SIZE 
    set or adjust the file size by SIZE 
SIZE may also be prefixed by one of the following modifying characters: 
    '+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down 
    to multiple of, '%' round up to multiple of.