Почему при использовании ActivePerl необходимо указывать ключ -i с расширением для резервного копирования? - PullRequest
23 голосов
/ 11 апреля 2010

Я не могу заставить работать на месте редактирование однострочников Perl, работающих под ActivePerl, если я не укажу их с расширением резервного копирования:

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

Та же команда с -i.bak или -i.orig обрабатывает запрос, но создает в процессе нежелательный файл резервной копии.

Есть ли способ обойти это?

Ответы [ 2 ]

32 голосов
/ 11 апреля 2010

Это ограничение Windows / MS-DOS. Согласно perldiag :

Вы находитесь в системе, такой как MS-DOS, которая запутывается, если вы пытаетесь читать из удаленного (но все еще открытого) файла. Вы должны сказать -i.bak, или что-то подобное.

Реализация -i в Perl заставляет его удалить file1.txt, сохраняя открытый дескриптор, а затем заново создать файл с тем же именем. Это позволяет вам «прочитать» файл file1.txt, даже если он был удален и создается заново. К сожалению, Windows / MS-DOS не позволяет вам удалить файл, к которому прикреплен открытый дескриптор, поэтому этот механизм не работает.

Лучше всего использовать -i.bak, а затем удалить файл резервной копии. Это, по крайней мере, дает вам некоторую защиту - например, вы можете отказаться от удаления резервной копии, если perl завершается с ненулевым кодом выхода. Что-то вроде:

perl -i.bak -ape "splice...." file1.txt && del file1.bak
0 голосов
/ 11 ноября 2014

Сэмпл с рекурсивным изменением и удалением, оба найдены. Работает, например, на Mingw Git Bash на 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

Двоичные завершенные значения, передаваемые между find / xargs для обработки пробелов. Необычный префикс с / во избежание искажения XML в поисковом запросе. Это предполагает, что у вас не было никаких файлов .bak для начала.

...