Es gibt bestimmte Zeilen, die ich aus einer Datei entfernen möchte. Nehmen wir an, es ist Zeile 20-37 und dann Zeile 45. Wie würde ich das tun, ohne den Inhalt dieser Zeilen anzugeben?
Es gibt bestimmte Zeilen, die ich aus einer Datei entfernen möchte. Nehmen wir an, es ist Zeile 20-37 und dann Zeile 45. Wie würde ich das tun, ohne den Inhalt dieser Zeilen anzugeben?
Antworten:
Mit sed
, wie so:
sed '20,37d; 45d' < input.txt > output.txt
Wenn Sie dies vor Ort tun wollten:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU
sed 'erstellt dazu eine temporäre Datei und die Ausgabe an diese Datei anstatt an die Standardausgabe senden. "... Ich kenne kein anderes" sed ", aber die Logistik des Aktualisierens" an Ort und Stelle "mit einem Stream- Editor" berechnet "nicht :)
Wenn die Datei bequem in den Speicher passt, könnten Sie auch verwenden ed
.
Die Befehle sind denen oben sehr ähnlich, sed
mit einem bemerkenswerten Unterschied : Sie müssen die Liste der zu löschenden Zeilennummern / -bereiche in absteigender Reihenfolge (von der höchsten Zeilennummer / -bereich bis zur niedrigsten) übergeben. Der Grund dafür ist, dass beim Löschen / Einfügen / Teilen / Verbinden von Zeilen mit ed
der Textpuffer nach jedem Unterbefehl aktualisiert wird. Wenn Sie also einige Zeilen löschen, befinden sich die restlichen folgenden Zeilen nicht mehr an derselben Position im Puffer, wenn die nächster Unterbefehl wird ausgeführt. Sie müssen also rückwärts beginnen 1 .
In-Place- Bearbeitung:
ed -s in_file <<IN
45d
20,37d
w
q
IN
oder
ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
oder
printf '%s\n' 45d 20,37d w q | ed -s in_file
Ersetzen Sie w
rite durch ,p
rint, wenn Sie die resultierende Ausgabe drucken möchten, anstatt in eine Datei zu schreiben. Wenn Sie die ursprüngliche Datei beibehalten und in eine andere Datei schreiben möchten, können Sie den neuen Dateinamen an den w
Unterbefehl rite übergeben:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
Sofern Sie nicht bereit sind, die neuen Zeilennummern nach jedem d
Elete zu berechnen , was für diesen speziellen Fall ziemlich trivial ist (nach dem Löschen der Zeilen 20-37, dh 18 Zeilen, wird Zeile 45 zu Zeile 27), können Sie Folgendes ausführen:
ed -s in_file <<IN
20,37d
27d
w
q
IN
Wenn Sie jedoch mehrere Zeilennummern / -bereiche löschen müssen, ist das Rückwärtsarbeiten ein Kinderspiel.
q
Befehl am Ende nützlich? Ich denke, es geht so oder so.
Lies es einfach in den Speicher, ändere es und schreibe es zurück. Sie können so etwas tun
filename = "foo"
f = open(filename, 'r+')
linenums = [1, 3]
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()
Getestet mit einer 5-zeiligen Datei. Danksagung für http://pleac.sourceforge.net/pleac_python/fileaccess.html , siehe Abschnitt "Ändern einer Datei ohne temporäre Datei". Siehe auch https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python
Einige Notizen:
Man könnte die Datei zuerst abschneiden, dann darauf schreiben, anstatt wie oben beschrieben zu schreiben und dann abzuschneiden. Ich kenne jedoch kein Python-Flag, mit dem man lesen und dann einen abgeschnittenen Schreibvorgang ausführen kann. Aber vielleicht fehlt mir etwas, da das Dokument nicht so klar ist. Welches bringt mich zu
Manchmal saugen die Python-Dokumente wirklich. Siehe http://docs.python.org/library/functions.html#open
Die Modi 'r +', 'w +' und 'a +' öffnen die Datei zum Aktualisieren (beachten Sie, dass 'w +' die Datei abschneidet).
Bedeutet das etwas für Sie? Was zum Teufel ist "offen für Updates"?
Ich weiß nicht, ob es besser ist, dies in Python zu tun, als in etwas Unixigem wie dem Stream-Editor. Es ist vielleicht portabler, aber ich weiß nicht, wie portabel sed ist. Ich habe es einfach so geschrieben, weil ich mit Low-Level-Programmierung besser zurechtkomme als mit klassischen Unix-Tools, die gut sind, wenn sie genau das tun, was Sie wollen, aber (glaube ich) im Allgemeinen weniger flexibel sind.
Dieser Ansatz (Manipulieren der Datei im Speicher) tauscht Speicher gegen Speicherplatz. Es sollte auf Computern mit ein paar GB Arbeitsspeicher für Dateien bis zu ein paar hundert MB funktionieren. Python verarbeitet Zeichenfolgen nicht sehr effizient. Ein Wechsel zu C / C ++ beispielsweise würde die Leistung geringfügig verbessern und die Speichernutzung erheblich verringern.
Sie können Vim im Ex-Modus verwenden:
ex -sc '20,37d|45d|x' file
d
löschen
x
speichern und schließen