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
kickass13
quelle

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
Jordanien
quelle
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.

AsymLabs
quelle
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

quelle
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

waue0920
quelle
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
iruvar
quelle
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
starfry
quelle
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

Steven Penny
quelle
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
Ritesh Singh
quelle
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

Vivek Parikh
quelle
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
Hongbo Liu
quelle
-2

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

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

user215264
quelle
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