767 Stimmen

Wie kann ich die erste Zeile einer Textdatei mit einem bash/sed-Skript entfernen?

Ich muss wiederholt die erste Zeile aus einer großen Textdatei mit Hilfe eines Bash-Skripts entfernen.

Zurzeit verwende ich sed -i -e "1d" $FILE - aber es dauert etwa eine Minute, bis die Löschung erfolgt.

Gibt es eine effizientere Möglichkeit, dies zu erreichen?

15voto

paxdiablo Punkte 809679

Nein, effizienter geht's nicht. Sie könnten ein C-Programm schreiben, das die Aufgabe etwas schneller erledigen könnte (weniger Startzeit und Verarbeitung von Argumenten), aber es wird wahrscheinlich zur gleichen Geschwindigkeit wie sed tendieren, wenn die Dateien groß werden (und ich nehme an, sie sind groß, wenn es eine Minute dauert).

Aber Ihre Frage leidet unter dem gleichen Problem wie so viele andere, dass sie die Lösung voraussetzt. Wenn Sie uns im Detail sagen würden was die Sie zu tun versuchen, anstatt wie können wir Ihnen vielleicht eine bessere Lösung vorschlagen.

Wenn es sich zum Beispiel um eine Datei A handelt, die von einem anderen Programm B verarbeitet wird, wäre eine Lösung, die erste Zeile nicht zu entfernen, sondern das Programm B so zu ändern, dass es sie anders verarbeitet.

Angenommen, alle Ihre Programme hängen an diese Datei A an, und Programm B liest und verarbeitet derzeit die erste Zeile, bevor es sie löscht.

Sie könnten das Programm B so umgestalten, dass es nicht versucht, die erste Zeile zu löschen, sondern einen dauerhaften (wahrscheinlich dateibasierten) Offset in der Datei A beibehält, so dass es beim nächsten Lauf diesen Offset aufsuchen, die Zeile dort verarbeiten und den Offset aktualisieren kann.

Dann könnte es zu einer ruhigen Zeit (Mitternacht?) eine spezielle Verarbeitung der Datei A durchführen, um alle derzeit verarbeiteten Zeilen zu löschen und den Versatz wieder auf 0 zu setzen.

Für ein Programm ist es sicherlich schneller, eine Datei zu öffnen und zu suchen, als sie zu öffnen und neu zu schreiben. Diese Diskussion setzt natürlich voraus, dass Sie die Kontrolle über Programm B haben. Ich weiß nicht, ob das der Fall ist, aber vielleicht gibt es andere mögliche Lösungen, wenn Sie weitere Informationen zur Verfügung stellen.

13voto

Mark Reed Punkte 85468

Wenn Sie die Datei an Ort und Stelle ändern wollen, können Sie immer das Original verwenden ed anstelle seiner s treuer Nachfolger sed :

ed "$FILE" <<<$'1d\nwq\n'

El ed Befehl war der ursprüngliche UNIX-Texteditor, bevor es überhaupt Vollbildterminals gab, geschweige denn grafische Workstations. Der ex Editor, am besten bekannt als der, den Sie verwenden, wenn Sie an der Eingabeaufforderung für den Doppelpunkt in vi ist ein ex gepflegte Version von ed so dass viele der gleichen Befehle funktionieren. Während ed ist für die interaktive Nutzung gedacht, kann aber auch im Stapelverarbeitungsmodus verwendet werden, indem eine Reihe von Befehlen an das Programm gesendet wird, wie es bei dieser Lösung der Fall ist.

Die Reihenfolge <<<$'1d\nwq\n' nutzt die Unterstützung moderner Shells für here-Zeichenketten ( <<< ) und ANSI-Anführungszeichen ( $' ... ' ) zur Einspeisung in die ed Befehl, der aus zwei Zeilen besteht: 1d die d löscht Zeile 1 und dann wq die w die Datei zurück auf die Festplatte und dann q Beendet die Bearbeitungssitzung.

11voto

Robert Gamble Punkte 101657

Wie Pax schon sagte, werden Sie wahrscheinlich nicht schneller sein als jetzt. Der Grund ist, dass es fast keine Dateisysteme gibt, die das Abschneiden vom Anfang der Datei unterstützen, so dass dies ein O( n ) Operation, bei der n ist die Größe der Datei. Was Sie tun können viel Schneller ist es, die erste Zeile mit der gleichen Anzahl von Bytes zu überschreiben (vielleicht mit Leerzeichen oder einem Kommentar), was für Sie funktionieren könnte, je nachdem, was genau Sie zu tun versuchen (was ist das eigentlich?).

11voto

alexis Punkte 46051

Vous kann die Dateien an Ort und Stelle bearbeiten: Verwenden Sie einfach die Perl-Funktion -i Flagge, etwa so:

perl -ni -e 'print unless $. == 1' filename.txt

Dadurch verschwindet die erste Zeile, wie von Ihnen gewünscht. Perl muss die gesamte Datei lesen und kopieren, aber es sorgt dafür, dass die Ausgabe unter dem Namen der Originaldatei gespeichert wird.

7voto

serup Punkte 3258

Sollte die Zeilen mit Ausnahme der ersten Zeile anzeigen:

cat textfile.txt | tail -n +2

CodeJaeger.com

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.

Powered by:

X