Как изменить, удалить или вставить строку в файл, или добавить в начало файла в Perl?
люди продолжают задавать этот вопрос, и я продолжаю отвечать на него тем же ответом от perlfaq5. Теперь это то, на что мы можем указать на Stackoverflow.
1 ответов
С perlfaq5:
основная идея вставки, изменения или удаления строки из текстового файла включает в себя чтение и печать файла до точки, в которую вы хотите внести изменения, внесение изменений, а затем чтение и печать остальной части файла. Perl не обеспечивает произвольный доступ к строкам (особенно с разделителем ввода записи,$/, является изменяемым), хотя такие модули, как Tie:: File фейк это.
На Perl программа для выполнения этих задач принимает основную форму-открытие файла, печать его строк, затем закрытие файла:
open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";
while( <$in> )
    {
    print $out $_;
    }
close $out;
в этой базовой форме добавьте детали, которые необходимо вставить, изменить или удалить строки.
чтобы добавить строки в начало, распечатайте эти строки перед вводом цикла, который печатает существующие строки.
open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";
print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC
while( <$in> )
    {
    print $out $_;
    }
close $out;
чтобы изменить существующие строки, вставьте код для изменения строк внутри while петли. В этом случае код находит все строчные версии "perl" и прописные буквы. Это происходит для каждой строки, поэтому убедитесь, что вы должны делать это на каждой строке!
open my $in,  '<',  $file      or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";
print $out "# Add this line to the top\n";
while( <$in> )
    {
    s/\b(perl)\b/Perl/g;
    print $out $_;
    }
close $out;
чтобы изменить только определенную строку, Номер входной строки,$., это полезно. Сначала прочитайте и распечатайте строки до той, которую вы хотите изменить. Затем прочитайте одну строку, которую вы хотите изменить, измените ее и распечатайте. После этого прочитайте остальные строки и распечатайте их:
while( <$in> )   # print the lines before the change
    {
    print $out $_;
    last if $. == 4; # line number before change
    }
my $line = <$in>;
$line =~ s/\b(perl)\b/Perl/g;
print $out $line;
while( <$in> )   # print the rest of the lines
    {
    print $out $_;
    }
чтобы пропустить строки, используйте управление циклом. The next в этом примере пропускает строки комментариев и last останавливает всю обработку как только он сталкивается либо __END__ или __DATA__.
while( <$in> )
    {
    next if /^\s+#/;             # skip comment lines
    last if /^__(END|DATA)__$/;  # stop at end of code marker
    print $out $_;
    }
сделайте то же самое, чтобы удалить определенную строку с помощью next, чтобы пропустить строки, которые вы не хотите показывать в выходные. Этот пример пропускает каждую пятую строку:
while( <$in> )
    {
    next unless $. % 5;
    print $out $_;
    }
если по какой-то странной причине вы действительно хотите увидеть весь файл сразу, а не обрабатывать строку за строкой, вы может хлебать его (до тех пор, пока вы можете поместить все это в память!):
open my $in,  '<',  $file      or die "Can't read old file: $!"
open my $out, '>', "$file.new" or die "Can't write new file: $!";
my @lines = do { local $/; <$in> }; # slurp!
    # do your magic here
print $out @lines;
модули, такие как File:: Slurp и Tie:: File может помочь с этим тоже. Если вы можете, однако, избежать чтения всего файла сразу. Perl не вернет эту память операционной системе до завершения процесса.
вы также можете использовать Perl one-liners для изменения файла на месте. Следующие изменения все "Фред" на "Барни" в inFile.txt, переписывая файл с новым содержимым. С -p переключатель, Perl обертывает while петли вокруг кода, который вы указываете с -e и -i включает редактирование на месте. Текущая строка находится в $_. С -p, Perl автоматически печатает значение $_ в конце цикла. См.perlrun для более подробной информации.
perl -pi -e 's/Fred/Barney/' inFile.txt
сделать резервную копию inFile.txt, дать -i расширение файла, чтобы добавить:
perl -pi.bak -e 's/Fred/Barney/' inFile.txt
изменить только пятую строку, вы можете добавить тестовую проверку $., номер строки входного сигнала, после этого только выполняет деятельность когда тест проходит:
perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt
чтобы добавить строки перед определенной строкой, вы можете добавить строку (или строки!) до Perl выводит $_:
perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt
вы даже можете добавить строку в начало файла, так как текущая строка печатается в конце цикла:
perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt
чтобы вставить строку после одной уже в файле, используйте -n переключатель. Это как ...  -p кроме того, что он не печатает $_ в конце цикла, так что вы должны сделать это сами. В этом случае print $_ во-первых, затем распечатать строку, которую вы хотите добавить.
perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt
удалить строки, печатать только те, которые вы хотите.
perl -ni -e 'print unless /d/' inFile.txt
    ... or ...
perl -pi -e 'next unless /d/' inFile.txt
