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

В Perl, как мне изменить, удалить или вставить строку в файл или добавить к началу файла?

Я хочу внести изменения в содержимое файла, изменив, удалив или вставив строки или добавив в начало файла. Как я могу сделать это в Perl?


Это вопрос из официальный FAQ. Мы импортируем perlfaq в Stack Overflow.

4b9b3361

Ответ 1

(Это официальный ответ официальный perlfaq, минус любые последующие изменения)

Основная идея вставки, изменения или удаления строки из текстового файла включает в себя чтение и печать файла до того момента, когда вы хотите сделать изменение, внесение изменений, затем чтение и печать остальной части файла. 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 THE MAGIC

while( <$in> )
    {
    print $out $_;
    }

close $out;

Чтобы изменить существующие строки, вставьте код, чтобы изменить строки внутри в то время как цикл. В этом случае код находит все нижние версии "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 $_;
    }

Чтобы пропустить строки, используйте элементы управления циклом. Следующий в этом примере пропускает строки комментариев, а последняя останавливает всю обработку, как только она встречается __END__ или __DATA__.

while( <$in> )
    {
    next if /^\s+#/;             # skip comment lines
    last if /^__(END|DATA)__$/;  # stop at end of code marker
    print $out $_;
    }

Сделайте то же самое, чтобы удалить определенную строку, используя следующую команду, чтобы пропустить строки, которые вы не хотите отображать на выходе. Этот пример пропускает каждый пятая строка:

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 для изменения файла на месте. Следующие изменяет все "Fred" на "Barney" в 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, за исключением того, что он не печатает $_ в конце цикла, поэтому вы должны сделать это сами. В этом случае сначала напечатайте $_, затем распечатайте которую вы хотите добавить.

perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt

Чтобы удалить строки, напечатайте только те, которые вы хотите.

perl -ni -e 'print unless /d/' inFile.txt

& hellip; или & hellip;

perl -pi -e 'next unless /d/' inFile.txt