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

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


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

(Это официальный ответ 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'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 $_; } 

Чтобы пропустить строки, используйте элементы управления циклом. Следующий в этом примере пропускает строки комментариев, а последний останавливает всю обработку после того, как он встретит либо __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 one-liners для изменения файла на месте. Следующее изменяет все «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 

… или …

 perl -pi -e 'next unless /d/' inFile.txt 
  • Разница между методами добавления и расширения списка в Python
  • jQuery с добавлением эффектов
  • Давайте будем гением компьютера.