сказано в perlrun
Обратите внимание, что, поскольку -i
переименовывает или удаляет исходный файл перед созданием нового файла с тем же именем, мягкие и жесткие ссылки в стиле Unix не будут сохранены.
Так что нельзя сделать это с -i
.
Вот еще один способ с Perl (как помечено - даже если есть чистое решение с sed
)
Я использую файлы a.txt
, b.txt
, их символические ссылки (ln -s a.txt ln_a.txt
и т. Д.) И c.txt
(и любой контент подходит для этого теста), а также список имен ссылок и c.txt
в файле
ln_a.txt ln_b.txt c.txt # file "input_list.txt"
где имена файлов / ссылок в input_list.txt
могут быть разделены пробелами или переводами строки.
Затем откройте временный выходной файл в первой строке каждого входного файла и запишите в него каждую обработанную строку. Как только будет достигнут конец входного файла, переименуйте этот временный вывод в его входной файл или в его цель, если это ссылка. Таким образом, для каждого входного файла перезаписать файл или его цель, если ссылка, с выходным файлом.
cat input_list.txt | xargs perl -MPath::Tiny -ne'
if ($.==1) { $tf = $ARGV."_tmp.$$"; $fh = path($tf)->openw };
s/(\w+)/$1-NEW/;
print $fh $_;
if (eof) { close ARGV; rename $tf, (-l $ARGV ? readlink $ARGV : $ARGV) }
'
Это изменяет содержание целей и оставляет ссылки в покое. Это работает и для обычных файлов.
Временное имя выходного файла (filename_tmp.$$
) может быть правильно задано с помощью File::Temp
или, скорее, с помощью Path :: Tiny :: tempfile , так как этот модуль уже используется.
переименовать , вероятно, следует изменить на move
с File :: Copy , для переносимости.
Используемое eof проверяет, не исчерпан ли файл для каждого входного файла, после чего выходной файл переименовывается во входной файл или в его цель. -l
является оператором проверки файлов , который проверяет, является ли файл в наличии символической ссылкой, и если это так, то readlink разрешает ссылку.
Безопасно rename
входной файл или цель в это время, так как он был прочитан и обработан.
$ ARGV - это имя
обработанного в данный момент файла, и ARGV - дескриптор файла для него.
Явное close ARGV
сбрасывает счетчик строк, чтобы мы могли открывать временные выходные данные в начале каждого нового входного файла, проверяя счетчик номера строки $. против 1
.