2010-12-08 1 views
25

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


Это question из official FAQ. Мы importing the perlfaq to Stack Overflow.

+0

возможно дубликат [Как изменить, удалить или вставить строку в файл или добавить в начало файла в Perl?] (Http://stackoverflow.com/questions/2322140/ How-do-i-change-delete-or-insert-a-line-in-a-file-or-append-to-the-start) – 2011-11-06 12:35:26

ответ

41

(Это official perlfaq answer, минус любые последующие правки)

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

Для изменения существующих строк, вставьте код для изменения строк внутри во время цикла. В этом случае код находит все нижние версии «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, дать -IA расширение файла добавить:

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 
+0

`perl -ni -e 'print if/d /' inFile .txt` действительно работал для удаления совпадающих строк, но `perl -pi -e 'next, если/d /' inFile.txt` не выполнялся. Также не изменилось «next if» на `next if`. Это с perl 5.10.0. Любая идея, что происходит? – 2014-10-03 00:19:17