Как изменить, удалить или вставить строку в файл, или добавить в начало файла в 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