In Dateien eines Verzeichnisbaums wollen wir eine mehrzeilige
Ersetzung vornehmen. Unter Nutzung von Perl geht dies mit einem Einzeiler:
$ find DIR ... | xargs perl -0777 -p -i -E 's/REGEX/REPLACEMENT/gms'
Hierbei ist REGEX ein Regulärer Ausdruck, der Text über
mehreren Zeilen matchen kann. Wie funktioniert der Aufruf?
Perl verarbeitet die Dateien, die von xargs(1) als Argumente übergeben
werden, und behandelt sie gemäß den angegebenen Optionen:
- -0777
-
Kein Input-Separator, d.h. Perl liest die jeweilige Datei komplett
ein statt sie zeilenweise zu verarbeiten. Dadurch wirkt der
Perl-Code, siehe Option -E CODE, nicht auf eine einzelne Zeile,
sondern auf den gesamten Dateiinhalt.
- -p
-
Perl iteriert über die Dateien, die als Argumente angegeben sind,
und gibt den Dateiinhalt jeweils nach Manipulation durch den Perl-Code
CODE mit print aus.
- -i
-
Die Ausgabe mit print ersetzt den Inhalt der ursprünglichen Datei
(Bearbeitung "in place"). Wird die Option -i mit einem Wert
ergänzt, z.B. -i.orig, bleibt die Originaldatei mit der Endung
.orig erhalten. Auf diesem Weg kann Code CODE
gefahrlos getestet werden.
- -E CODE
-
Der Perl-Code, der auf den Inhalt der Datei angewandt wird. Dieser
kann beliebige Manipulationen vornehmen. Wir führen oben ein
einzelnes Substitute s/// aus, mit den Optionen g (alle
Fundstellen werden ersetzt), m (^ uns $ matchen
Zeilenanfang und Zeilenende), s (der Punkt . matcht auch
Zeilenumbrüche). Diese Semantik ist in dem gegebenen Anwendungsfall
besonders nützlich.
Beispiel
Entferne im Verzeichnisbaum DIR die Inline-Dokumentation (POD)
aus allen .pm-Dateien:
$ find DIR -name '*.pm' | xargs perl -0777 -p -i -E 's/^=[a-z].*?^=cut\n//gms'