Wie lösche ich die ersten n Zeilen einer ASCII-Datei mit Shell-Befehlen?


92

Ich habe mehrere Dateien, die ASCII-Textinformationen in den ersten 5-10 Zeilen enthalten, gefolgt von gut tabellierten Matrixinformationen. In einem Shell-Skript möchte ich diese ersten Textzeilen entfernen, damit ich die reinen Matrixinformationen in einem anderen Programm verwenden kann. Wie kann ich dazu Bash-Shell-Befehle verwenden?

Wenn es Hilfe gibt, verwende ich RedHat und ein Ubuntu-Linux-System.

Antworten:


143

Solange die Datei kein Symlink oder Hardlink ist, können Sie sed, tail oder awk verwenden. Beispiel unten.

$ cat t.txt
12
34
56
78
90

sed

$ sed -e '1,3d' < t.txt
78
90

Sie können auch ohne eine temporäre Datei sed an Ort und Stelle benutzen sed -i -e 1,3d yourfile. Dies wird nichts wiedergeben, sondern lediglich die Datei direkt ändern. Wenn Sie das Ergebnis nicht an einen anderen Befehl weiterleiten müssen, ist dies einfacher.

Schwanz

$ tail -n +4 t.txt
78
90

awk

$ awk 'NR > 3 { print }' < t.txt
78
90

8
Sie können auch ohne eine temporäre Datei sed an Ort und Stelle benutzen sed -i -e 1,3d yourfile. Dies wird nichts wiedergeben, sondern lediglich die Datei direkt ändern. Wenn Sie das Ergebnis nicht an einen anderen Befehl weiterleiten müssen, ist dies einfacher.
Yanick Girouard

1
Vielen Dank @YanickGirouard, @IgnacioVazquezAbrams! Ihr zwei habt mir gerade eine Menge Handarbeit bei meinen Nachforschungen erspart! :)
Paul

2
@ Svetlana sed -ispeziell. Die meisten Implementierungen löschen einfach die Datei und ersetzen sie durch eine neue, was bei Links nicht funktioniert, da Sie das Original an seinem anderen Speicherort belassen.
JW013

6
wie wäre es zu erklären, was '1,3d', +4, et.c. meint? Die Frage galt für n Zeilen, aber Sie haben nicht gesagt, was n ist (wie anscheinend n 2 in Ihren Beispielen ist, obwohl es für einen Neuling nicht offensichtlich ist, was geändert werden muss, um n zu ändern)
Robin Manoli

3
Dies verwendet eine temporäre Datei, die für eine 100% ige Auslastung des Festplattenspeichers nicht sehr nützlich ist. Wäre interessant, eine Lösung zu haben, die dies buchstäblich "vor Ort" macht.
Shai

10

sed -i '1,3d' file.txt

Dadurch werden die ersten 3 Zeilen aus der Datei file.txt gelöscht.


6

Wenn es sich bei den tabellierten Zeilen um Zeilen mit Tabulatorzeichen handelt:

grep '␉' <input_file >output_file

( als wörtliches Tabulatorzeichen) oder gleichwertig

sed -n '/␉/p' <input_file >output_file

In einem bash / ksh / zsh-Skript können Sie $'\t'für eine Registerkarte schreiben , z . B. grep $'\t'oder sed -n $'/\t/p'.

Wenn Sie 10 Zeilen am Anfang der Datei entfernen möchten:

tail -n +11 <input_file >output_file

(Beachten Sie +11, dass 10 Zeilen entfernt werden sollen, da +11dies "ab Zeile 11 beginnen" bedeutet und die Zeilen mit den Endnummern von 1 beginnen) oder

sed '1,10d' <input_file >output_file

Unter Linux können Sie die -iOption von GNU sed nutzen , um Dateien direkt zu ändern:

sed -i -n '/\t/p' *.txt

Oder Sie können eine Shell-Schleife und temporäre Dateien verwenden:

for x in *.txt; do
  tail -n +11 <"$x" >"$x.tmp"
  mv "$x.tmp" "$x"
done

Oder wenn Sie die Dateien nicht ändern möchten, sondern stattdessen einen anderen Namen vergeben möchten:

for x in *.txt; do
  tail -n +11 <"$x" >"${x%.txt}.data"
done

3
"tabellarisch" bedeutet normalerweise "hübsch in einer Tabelle gedruckt", nicht "mit Tabulatorzeichen eingerückt".
Ignacio Vazquez-Abrams

@ IgnacioVazquez-Abrams Ich weiß. Die hübsch gedruckte Tabelle verwendet manchmal Tabulatorzeichen, die leichter zu erkennen sind als ausgerichtete Spalten. Natürlich könnte ich einen besseren Matcher geben, wenn Paul einen Sample-Input geben würde.
Gilles

2

Sie können Vim im Ex-Modus verwenden:

ex -sc '1d5|x' file
  1. 1 in die erste Zeile gehen

  2. 5 Wählen Sie 5 Zeilen

  3. d löschen

  4. x speichern und schließen


0

echo "a \ nb" | sed '1d' # löscht die erste Zeile

cat list.txt | sed '1d'> list.csv # list.txt lesen und list.csv ohne erste Zeile schreiben

Andere nützliche Befehle:

grep '^ |' # findet erstes Zeichen (Pipe |)

sed 's / | // g' # löscht die Pipe

sed 's / // g' # löscht Leerzeichen


0

Prozentual

Verwenden Sie bash, um eine Datei mit einer Prozentzahl anstelle einer absoluten Anzahl von Zeilen zu bereinigen:

sed -i -e 1,$( printf  "$((`cat php_errors.log | wc -l` * 75 /100 ))" )d php_errors.log

Beachten Sie, dass dieser Befehl destruktiv sein kann, da er den Inhalt direkt löscht, ohne eine Kopie zu erstellen.

Die ersten 75% der Zeilen werden aus der genannten Datei gelöscht.

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.