Frage

Ich mag aus einer Datei einer oder mehr bestimmten Zeilennummern löschen. Wie würde ich dies unter Verwendung von sed tun?

War es hilfreich?

Lösung

Wenn Sie Zeilen löschen 5 bis 10 und 12:

sed -e '5,10d;12d' file

Damit werden die Ergebnisse auf dem Bildschirm drucken. Wenn Sie die Ergebnisse auf die gleiche Datei speichern:

sed -i.bak -e '5,10d;12d' file

Dadurch wird die Datei bis zu file.bak zurück, und löschen Sie die gegebenen Linien.

. Hinweis: Die Zeilennummern beginnen bei 1. Die erste Zeile der Datei 1, nicht 0

Andere Tipps

Sie können eine bestimmte einzelne Zeile mit Zeilennummer löschen, indem Sie    sed -i '33d' Datei

Dies wird die Linie auf 33 Zeilennummer löschen und die aktualisierte Datei speichern.

und awk als auch

awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$ 

Dies ist sehr oft ein Symptom für eine Antipattern. Das Werkzeug, das die Zeilennummern erzeugt wird, kann auch mit einer ersetzt werden, die direkt den Zeilen löschen. Zum Beispiel:

grep -nh error logfile | cut -d: -f1 | deletelines logfile

(wobei deletelines ist das Dienstprogramm Sie stellen sich vor, Sie brauchen) ist die gleiche wie

grep -v error logfile

sagte, hat, wenn Sie in einer Situation sind, wo Sie wirklich diese Aufgabe ausführen müssen, können Sie einen einfachen sed Skript aus der Datei der Zeilennummern erzeugen können. Humoristisch (aber vielleicht etwas verwirrend) Sie können dies tun, mit sed.

sed 's%$%d%' linenumbers

Dies eine Datei von Zeilennummern akzeptiert, einem pro Zeile, und erzeugt auf der Standardausgabe, die gleichen Zeilennummern mit d nach jedem angehängt. Dies ist eine gültige sed Skript, das wir in eine Datei speichern können, oder (auf einigen Plattformen) Rohr an einem anderen sed Beispiel:

sed 's%$%d%' linenumbers | sed -f - logfile

Auf einigen Plattformen sed -f versteht nicht die Option Argument - Standardeingabe zu verstehen, so dass Sie das Skript in eine temporäre Datei zu umleiten haben, und reinigen Sie es, wenn Sie fertig sind, oder vielleicht den einsamen Strich mit /dev/stdin ersetzen oder /proc/$pid/fd/1 wenn Ihr Betriebssystem (oder Schale) hat den.

Wie immer können Sie -i vor der -f Option hinzufügen sed bearbeiten die Zieldatei an seinem Platz zu haben, anstatt das Ergebnis auf der Standardausgabe zu erzeugen. An * BSDish Plattformen (einschließlich OSX) benötigen Sie ein explizites Argument -i zu liefern als auch, eine gemeinsame Idiom ist ein leeres Argument zu liefern; -i ''.

Ich möchte eine Verallgemeinerung mit awk vorzuschlagen.

Wenn die Datei durch die Blöcke einer festen Größe gemacht wird und die Linien zu löschen sind für jeden Block wiederholt, awk kann fein in einer solchen Art und Weise arbeiten

awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print  $0}'
 OriginFile.dat > MyOutputCuttedFile.dat

In diesem Beispiel wird die Größe für den Block 2000, und ich mag die Linien drucken [1..713] und [1026..1029].

  • NR ist die Variable von awk verwendet, um die aktuelle Zeilennummer zu speichern.
  • % gibt den Rest (oder Modul) der Division zweier ganzer Zahlen;
  • nl=((NR-1)%BLOCKSIZE)+1 Hier schreiben wir in der Variablen nl die Zeilennummer innerhalb des aktuellen Blocks. (Siehe unten)
  • || und && ist der logische Operator ODER und und .
  • print $0 schreibt die durchgezogene Linie

Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
  +1   We add again 1 because we want to restore the desired order.

+-----+------+----------+------------+
| NR  | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
|  1  |  1   |    0     |     1      |
|  2  |  2   |    1     |     2      |
|  3  |  0   |    2     |     3      |
|  4  |  1   |    0     |     1      |
+-----+------+----------+------------+

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top