Ich habe eine Datei, foo.txt
die die folgenden Zeilen enthält:
a
b
c
Ich möchte einen einfachen Befehl, der den Inhalt von foo.txt
sein:
a
b
Ich habe eine Datei, foo.txt
die die folgenden Zeilen enthält:
a
b
c
Ich möchte einen einfachen Befehl, der den Inhalt von foo.txt
sein:
a
b
Verwendung von GNU sed
:
sed -i '$ d' foo.txt
En -i
Option existiert nicht in GNU sed
Versionen älter als 3.95, so dass Sie ihn als Filter mit einer temporären Datei verwenden müssen:
cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
In diesem Fall könnten Sie natürlich auch head -n -1
anstelle von sed
.
MacOS:
Unter Mac OS X (ab 10.7.4) ist das Äquivalent des Befehls sed -i
obiger Befehl ist
sed -i '' -e '$ d' foo.txt
Dies ist bei weitem die schnellste und einfachste Lösung, insbesondere bei großen Dateien:
head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
wenn Sie die oberste Zeile löschen wollen, verwenden Sie dies:
tail -n +2 foo.txt
was bedeutet, dass die Ausgabezeilen in Zeile 2 beginnen.
Nicht verwenden sed
für das Löschen von Zeilen am Anfang oder Ende einer Datei - es ist sehr, sehr langsam, wenn die Datei groß ist.
Ich hatte Schwierigkeiten mit allen Antworten hier, weil ich mit einer RIESIGEN Datei (~300Gb) arbeitete und keine der Lösungen skalierte. Hier ist meine Lösung:
filename="example.txt"
file_size="$(stat --format=%s "$filename")"
trim_count="$(tail -n1 "$filename" | wc -c)"
end_position="$(echo "$file_size - $trim_count" | bc)"
dd if=/dev/null of="$filename" bs=1 seek="$end_position"
Oder alternativ als One-Liner:
dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc )
In Worten: Ermitteln Sie die Länge der Datei, die Sie am Ende haben wollen (Länge der Datei minus Länge der letzten Zeile, mit bc
), und setzen Sie diese Position auf das Ende der Datei (durch dd
ein Byte von /dev/null
darauf).
Dies ist schnell, weil tail
beginnt mit dem Lesen vom Ende her, und dd
überschreibt die Datei an Ort und Stelle anstatt jede Zeile der Datei zu kopieren (und zu analysieren), wie es bei den anderen Lösungen der Fall ist.
HINWEIS: Dies entfernt die Zeile aus der Datei an Ort und Stelle! Machen Sie eine Sicherungskopie oder testen Sie es an einer Dummy-Datei, bevor Sie es an Ihrer eigenen Datei ausprobieren!
So entfernen Sie die letzte Zeile aus einer Datei ohne die gesamte Datei zu lesen oder etwas neu zu schreiben können Sie verwenden
tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
Um die letzte Zeile zu entfernen und sie auch auf stdout auszugeben ("pop"), können Sie diesen Befehl kombinieren mit tee
:
tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
Diese Befehle können eine sehr große Datei effizient verarbeiten. Dies ist ähnlich und inspiriert von Yossis Antwort, aber es vermeidet die Verwendung einiger zusätzlicher Funktionen.
Wenn Sie diese wiederholt verwenden und Fehlerbehandlung und einige andere Funktionen wünschen, können Sie die poptail
Befehl hier: https://github.com/donm/evenmoreutils
Auf dem Mac funktioniert head -n -1 nicht. Ich habe versucht, eine einfache Lösung zu finden, um dieses Problem nur mit den Befehlen "head" und/oder "tail" zu lösen, ohne mir Gedanken über die Verarbeitungszeit zu machen.
Ich habe die folgende Befehlsfolge ausprobiert und war froh, dass ich das Problem nur mit dem Befehl "tail" [ mit den auf dem Mac verfügbaren Optionen] lösen konnte. Wenn Sie also mit einem Mac arbeiten und nur "tail" verwenden möchten, um dieses Problem zu lösen, können Sie diesen Befehl verwenden:
cat file.txt | tail -r | tail -n +2 | tail -r
1> tail -r : kehrt einfach die Reihenfolge der Zeilen in seiner Eingabe um
2> tail -n +2 : gibt alle Zeilen ab der zweiten Zeile der Eingabe aus
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.