Подтвердить что ты не робот

Почему при использовании 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 работает с обработкой, но создает в ней файл нежелательной резервной копии.

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

4b9b3361

Ответ 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, которые можно было бы начать.