Почему при использовании ActivePerl я должен указать ключ -i с расширением резервной копии?
Я не могу получить на месте редактирование однострочных 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
работает с обработкой, но создает в ней файл нежелательной резервной копии.
Есть ли способ обойти это?
Ответы
Ответ 1
Это ограничение Windows/MS-DOS. Согласно perldiag:
Вы находитесь в такой системе, как MS-DOS, которая запутывается, если вы попытаетесь прочитать из удаленного (но все еще открытого) файла. Вы должны сказать -i.bak или некоторые из них.
Реализация Perl -i
заставляет его удалять file1.txt
, сохраняя в нем открытый дескриптор, а затем повторно создает файл с тем же именем. Это позволяет вам читать файл file1.txt, даже если он был удален и повторно создан. К сожалению, Windows/MS-DOS не позволяет вам удалять файл с прикрепленным к нему открытым дескриптором, поэтому этот механизм не работает.
Лучше всего использовать -i.bak
, а затем удалить файл резервной копии. Это, по крайней мере, дает вам некоторую защиту - например, вы можете отказаться от удаления резервной копии, если perl
выходит с ненулевым кодом выхода. Что-то вроде:
perl -i.bak -ape "splice...." file1.txt && del file1.bak
Ответ 2
Образец с рекурсивным изменением и удалением обоих выполняется путем поиска. Работает, например, mingw git bash в окнах.
$ 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 для обработки пробелов. Необычный s/prefix, чтобы избежать искажения xml в поисковом выражении. Предполагается, что у вас не было файлов .bak
, которые можно было бы начать.