Ich möchte eine oder mehrere bestimmte Zeilennummern aus einer Datei löschen. Wie würde ich das mit sed machen?
Ich möchte eine oder mehrere bestimmte Zeilennummern aus einer Datei löschen. Wie würde ich das mit sed machen?
Antworten:
Wenn Sie die Zeilen 5 bis 10 und 12 löschen möchten:
sed -e '5,10d;12d' file
Dadurch werden die Ergebnisse auf dem Bildschirm gedruckt. Wenn Sie die Ergebnisse in derselben Datei speichern möchten:
sed -i.bak -e '5,10d;12d' file
Dadurch wird die Datei gesichert file.bak
und die angegebenen Zeilen gelöscht.
Hinweis: Zeilennummern beginnen bei 1. Die erste Zeile der Datei ist 1, nicht 0.
sed -e '5,$d' file
sed -e '5d' file
. Die Syntax lautet <address><command>
; Dabei <address>
kann es sich entweder um eine einzelne Zeile 5
oder um einen Zeilenbereich handeln 5,10
, und der Befehl d
löscht die angegebene Zeile oder die angegebenen Zeilen. Die Adressen können auch reguläre Ausdrücke oder das Dollarzeichen sein $
, das die letzte Zeile der Datei angibt.
Sie können eine bestimmte einzelne Zeile mit ihrer Zeilennummer durch löschen
sed -i '33d' file
Dadurch wird die Zeile mit der Zeilennummer 33 gelöscht und die aktualisierte Datei gespeichert.
sed -i '0,/<TARGET>/{/<NEW_VALUE>/d;}' '<SOME_FILE_NAME>'
. Vielen Dank!
und awk 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 ein Antimuster. Das Werkzeug, mit dem die Zeilennummern erstellt wurden, kann durchaus durch ein Werkzeug ersetzt werden, mit dem die Zeilen sofort gelöscht werden. Beispielsweise;
grep -nh error logfile | cut -d: -f1 | deletelines logfile
(Wo deletelines
ist das Dienstprogramm, von dem Sie sich vorstellen, dass Sie es benötigen) ist dasselbe wie
grep -v error logfile
Wenn Sie sich jedoch in einer Situation befinden, in der Sie diese Aufgabe wirklich ausführen müssen, können Sie sed
aus der Datei mit den Zeilennummern ein einfaches Skript erstellen. Humorvoll (aber vielleicht etwas verwirrend) kann man das damit machen sed
.
sed 's%$%d%' linenumbers
Dies akzeptiert eine Datei mit Zeilennummern, eine pro Zeile, und erzeugt bei der Standardausgabe dieselben Zeilennummern, d
an die jeweils eine angehängt wird. Dies ist ein gültiges sed
Skript, das wir in einer Datei speichern oder (auf einigen Plattformen) an eine andere sed
Instanz weiterleiten können:
sed 's%$%d%' linenumbers | sed -f - logfile
Wenn Sie auf einigen Plattformen sed -f
das Optionsargument nicht als -
Standardeingabe verstehen , müssen Sie das Skript in eine temporäre Datei umleiten und es bereinigen, wenn Sie fertig sind, oder den einzelnen Bindestrich durch /dev/stdin
oder durch /proc/$pid/fd/1
Ihr Betriebssystem (oder Ihre Shell) ersetzen ) hat das.
Wie immer können Sie -i
vor der -f
Option hinzufügen , dass sed
die Zieldatei bearbeitet werden soll, anstatt das Ergebnis in der Standardausgabe zu erzeugen. Auf * BSDish-Plattformen (einschließlich OSX) müssen Sie ebenfalls ein explizites Argument angeben -i
. eine übliche Redewendung ist es, ein leeres Argument zu liefern; -i ''
.
p
stattdessen d
zusammen mit der Option -n
(es funktioniert nicht ohne -n
und !d
auch nicht).
Ich möchte eine Verallgemeinerung mit awk vorschlagen.
Wenn die Datei aus Blöcken fester Größe besteht und die zu löschenden Zeilen für jeden Block wiederholt werden, kann awk auf diese Weise einwandfrei funktionieren
awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print $0}'
OriginFile.dat > MyOutputCuttedFile.dat
In diesem Beispiel ist die Größe für den Block 2000 und ich möchte die Zeilen [1..713] und [1026..1029] drucken.
NR
ist die Variable, die von awk zum Speichern der aktuellen Zeilennummer verwendet wird.%
gibt den Rest (oder Modul) der Division von zwei ganzen Zahlen an;nl=((NR-1)%BLOCKSIZE)+1
Hier schreiben wir in die Variable nl die Zeilennummer innerhalb des aktuellen Blocks. (siehe unten)||
und &&
sind die logischen Operatoren OR und AND .print $0
schreibt die ganze ZeileWhy ((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 |
+-----+------+----------+------------+