29 Stimmen

Warum muss ich bei der Verwendung von ActivePerl den Schalter -i mit einer Backup-Erweiterung angeben?

Ich kann die In-Place-Bearbeitung von Perl-Einzeilern, die unter ActivePerl laufen, nicht zum Funktionieren bringen, es sei denn, ich gebe sie mit einer Backup-Erweiterung an:

C:\> perl -i -ape "splice (@F, 2, 0, q(inserted text)); $_ = qq(@F\n);" file1.txt
Can't do inplace edit without backup.

Derselbe Befehl mit -i.bak o -i.orig funktioniert einwandfrei, erzeugt dabei aber eine unerwünschte Sicherungsdatei.

Gibt es eine Möglichkeit, dies zu umgehen?

37voto

rjh Punkte 47430

Dies ist eine Windows/MS-DOS-Beschränkung. Laut perldiag :

Sie arbeiten mit einem System wie MS-DOS, das verwirrt wird, wenn Sie versuchen, aus einer gelöschten (aber noch geöffneten) Datei zu lesen. Sie müssen -i.bak oder ähnliches sagen.

Perls -i Implementierung bewirkt, dass es die file1.txt unter Beibehaltung eines offenen Handles, und erstellen Sie dann die Datei mit demselben Namen neu. Auf diese Weise können Sie Datei1.txt "lesen", obwohl sie gelöscht wurde und neu erstellt wird. Leider ist es unter Windows/MS-DOS nicht möglich, eine Datei mit einem offenen Handle zu löschen, so dass dieser Mechanismus nicht funktioniert.

Ihre beste Chance ist die Verwendung von -i.bak und löschen Sie dann die Sicherungsdatei. Dies bietet Ihnen zumindest einen gewissen Schutz - Sie könnten sich zum Beispiel dafür entscheiden, die Sicherung nicht zu löschen, wenn perl wird mit einem Exit-Code ungleich Null beendet. Etwa so:

perl -i.bak -ape "splice...." file1.txt && del file1.bak

0voto

shuckc Punkte 2585

Beispiel mit rekursivem Ändern und Löschen, beides mit find. Funktioniert z.B. mit mingw git bash unter Windows.

$ find . -name "*.xml" -print0 | xargs -0 perl -p -i.bak -e 's#\s*<property name="blah" value="false" />\s*##g'
$ find . -name "*.bak" -print0 | xargs -0 rm

Binär terminierte Werte, die zwischen find/xargs übergeben werden, um Leerzeichen zu behandeln. Ungewöhnliches s/-Präfix, um die Vermischung von xml im Suchbegriff zu vermeiden. Dies setzt voraus, dass Sie keine .bak Dateien herumliegen, um zu beginnen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X