Löschen Erste Zeile einer Datei


110

Wie kann ich die erste Zeile einer Datei löschen und die Änderungen beibehalten?

Ich habe es versucht, aber es löscht den gesamten Inhalt der Datei.

$sed 1d file.txt > file.txt

Antworten:


81

Der Grund, warum file.txt nach diesem Befehl leer ist, ist die Reihenfolge, in der die Shell die Dinge tut. Das erste, was mit dieser Leitung passiert, ist die Umleitung. Die Datei "file.txt" wird geöffnet und auf 0 Byte gekürzt. Danach wird der Befehl sed ausgeführt, aber zu diesem Zeitpunkt ist die Datei bereits leer.

Es gibt einige Optionen, die meisten beinhalten das Schreiben in eine temporäre Datei.

sed '1d' file.txt > tmpfile; mv tmpfile file.txt # POSIX
sed -i '1d' file.txt # GNU sed only, creates a temporary file

perl -ip -e '$_ = undef if $. == 1' file.txt # also creates a temporary file

2
Mit BSD sedkönnen Sie verwenden sed -i .bak '1d' file.txt.

1
Gibt es einen Weg, der keine temporäre Datei enthält? Auf jeden Fall wird dies den Trick tun. Danke vielmals!
Kickass13

@ kickass13 möglicherweise mit einem Texteditor wie ed.
Jordan

6
Der edBefehl wäre: printf "%s\n" 1d w q | ed file.txt(I heart ed)
Glenn Jackman

1
@jonayreyes-exec sed -i '1d' {} \;
jordanm

141

Eine sehr leichte Alternative besteht darin, alles außer der ersten Zeile "abzuschneiden" (dies kann eine einfache Möglichkeit sein, Dateikopfzeilen im Allgemeinen zu entfernen):

# -n +2 : start at line 2 of the file.
tail -n +2 file.txt > file.stdout

Im Anschluss an @Evan Teitelman können Sie:

tail -n +2 file.txt | sponge file.txt

So vermeiden Sie eine temporäre Datei. Eine andere Option könnte sein:

echo "$(tail -n +2 file.txt)" > file.txt

Und so weiter. Letzten testen:

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ echo "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5
[user@work ~]$ 

Hoppla, wir haben eine neue Zeile verloren (per @ 1_CR-Kommentar unten). Versuchen Sie stattdessen Folgendes:

printf "%s\n\n" "$(tail -n +2 file.txt)" > file.txt

[user@work ~]$ cat file.txt
line 1
line 2
line 3
line 4
line 5

[user@work ~]$ printf '%s\n\n' "$(tail -n +2 file.txt)" > file.txt
[user@work ~]$ cat file.txt
line 2
line 3
line 4
line 5  

[user@work ~]$ 

Kommen Sie zurück zu sed und versuchen Sie:

printf '%s\n\n' "$(sed '1d' file.txt)" > file.txt

oder vielleicht

echo -e "$(sed '1d' file.txt)\n" > file.txt

Nebenwirkungen zu vermeiden.


Ich habe es gerade auf meinem Fedora-System ausprobiert und die Ausgabe ist über. Sie haben Recht - danke, dass Sie darauf hingewiesen haben.
AsymLabs

Der tailTrick hat bei mir funktioniert (hat bei einer 130-MB-Datei weniger als 3 Sekunden gedauert). Vielen Dank!
Elo80ka

echo "$(tail -n +2 file.txt)" > file.txtist die perfekte Antwort.
Alex Raj Kaliamoorthy

Danke! echo "$ (tail -n +2 file.txt)"> file.txt funktioniert bei mir genauso wie ein charm!
Arsenii

16

Schauen Sie sich auch spongevon an moreutils. spongeHält Daten von der Standardeingabe ein, bis das Schreibende der Standardeingabe geschlossen wird, bevor in eine Datei geschrieben wird. Es wird so verwendet:

sed '1d' file.txt | sponge file.txt

14

Da dieses Thema von Interesse ist, teste ich den Benchmark auf drei Arten:

  1. sed '1d' d.txt > tmp.txt
  2. tail -n +2 d.txt > tmp.txt
  3. sed -i '1d' d.txt

Beachten Sie, dass das Ziel d.txteine 5,4-GB-Datei ist

Erhalten Sie das Ergebnis:


run 1 : sed '1d' d.txt > r1.txt
14s
run 2 : tail -n +2 d.txt > r2.txt
20s
run 3 : sed -i '1d' d.txt
88s

Fazit: Es scheint unten der schnellste Weg zu sein:

sed '1d' file.txt > tmpfile; mv tmpfile file.txt


Ihre sed '1d' d.txtMethode enthielt den mvBefehl nicht (so scheint es, als würde sie Ihre Tests lesen) . In meinen Tests auf FreeBSD mit einer 20MB-Datei sed -iwar das am schnellsten.
Sopalajo de Arrierez

9

exkann für die direkte Bearbeitung ohne temporäre Datei verwendet werden

ex -c ':1d' -c ':wq' file.txt

2
Ex verwendet eine temporäre Datei. strace -e open ex -c ':1d' -c ':wq' foo. ex schneidet die Originaldatei mit der temporären Datei ab, wobei die Option -i von GNU sed das Original mit der temporären Datei überschreibt. Ich bin mir nicht sicher, wie BSD sed funktioniert.
llua

@llua, du hast recht. Das habe ich auch gemerkt, aber später
iruvar

3

Der kürzeste und einfachste Weg, die erste Zeile aus einer Datei zu löschen, sedist:

$ sed -i -n -e '2,$p' file.txt

3

Sie können Vim im Ex-Modus verwenden:

ex -s -c '1d|x' file.txt
  1. 1 Erste Zeile finden

  2. d löschen

  3. x speichern und schließen


0

Dieser Befehl entfernt 1 Zeile und speichert als "file.txt".

sed '1d' file.txt  > /tmp/file.txt && mv /tmp/file.txt file.txt || rm -f /tmp/file.txt

0

So löschen Sie eine Praticiler-Zeile in einer Datei

  1. Erste Zeile löschen

Sed '1d' Datei

  1. Erste und dritte Zeile löschen

Sed '1d3d' Datei

Zeichen in Zeile löschen

1 Löschen Sie die ersten beiden Charter in lin

Sed 's /^..//' Datei

2 Löschen Sie die letzten beiden Zeilen

Sed 's / .. £ //' Datei

3 Leerzeile löschen

Sed '/ ^ £ / d' Datei


4
Haben die Briten die Kolonien zurückerobert? Das letzte Mal habe ich nachgesehen, £$.
G-Man

£ angegeben Doller Zeichen ..
Vivek Parikh

0

Könnte vim verwenden, um dies zu tun:

vim -u NONE +'1d' +wq! /tmp/test.txt

-2

Katze file01 | sed -e '1,3d'

// zeige Inhalt in file01 aber entferne die erste und dritte Zeile


2
Der Befehl sed entfernt die Zeilen 1, 2 und 3.
icarus

1
Dies löscht mehr als gewünscht und "behält die Änderungen nicht bei"
Jeff Schaller
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.