То же, что и на любом другом языке.
use Fcntl qw( SEEK_SET );
my $qfn = $ARGV[0];
open(my $fh, '+<', $qfn)
or die("Can't open \"$qfn\": $!\n");
# Read contents of file into $file.
my $file; { local $/; $file = <$fh>; }
if ($file =~ s/^.*SUBSTR.*/foo/mg) {
seek($fh, 0, SEEK_SET)
or die("seek: $!\n");
truncate($fh, 0)
or die("truncate: $!\n");
print($fh $file)
or die("print: $!\n");
close($fh)
or die("close: $!\n");
}
Другой способ:
- Создать временный файл в том же каталоге, что и исходный файл.
- Чтение из файла и запись измененного содержимого в новый файл.
- При возникновении ошибки удалите временную.
- Удалите оригинал.
- Переименуйте временный.
Это то, что происходит, когда вы делаете следующее при использовании достаточно свежей версии Perl:
perl -nle'print /SUBSTR/ ? "foo" : $_' -i file
Мы можем получить доступ к этой функции через $^I
$^I = '';
while (<>) {
chomp;
say /SUBSTR/ ? "foo" : $_;
}
У этого подхода есть два преимущества:
- Нет потери данных при ошибке.
- Это позволяет нам читать файл построчно (таким образом, экономя память) .
И три недостатка:
- Требуется достаточно места на диске как для исходного, так и для измененного файла.
- Требуется разрешение на создание нового файла.
- Файл теряет все права и полномочия, которые у него были изначально.