Как заменить строки в середине файла на Perl?
Я открываю файл в режиме добавления. Мне нужно заменить строки 2,3 и 4 в файле, а позже мне нужно добавить новые данные в конец файла.
5 ответов
я думаю, что это ответ FAQ, который я перепостил в Stackoverflow больше всего. The 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;
изменить только a конкретная линия,номер входной строки,$.
, это полезно. Сначала прочитайте и распечатайте строки до той, которую вы хотите изменить. Затем прочитайте одну строку, которую вы хотите изменить, измените ее и распечатайте. После этого прочитайте остальные строки и распечатайте их:
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 $_;
}
сделайте то же самое, чтобы удалить определенную строку, используя 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 для изменения файла на месте. Следующие изменения все 'Фред' to 'Barney' на inFile.txt, перезапись файла с новым содержимым. С -p
переключатель, Perl оборачивает петлю времени вокруг код, который вы указываете с помощью -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
вы можете сделать это с помощью Tie:: File. (Имейте в виду, что ему придется переписать весь файл, чтобы заменить начальные строки, но Tie::File скроет от вас детали.)
хорошая идиома Perl-это чтение и запись стандартного ввода и вывода. Вы можете перенаправлять и перенаправлять по мере необходимости. Через оператора (перенос в readline), Perl откроет файлы, которые вы передаете в качестве аргумента в командной строке.
чтобы ответить на ваш вопрос, несколько строк кода (как можно более чистым) :
#!/usr/bin/env perl
use strict; use warnings;
while (<>) {
if ($. == 2) {
print "new data", "\n";
next;
}
if ($. == 3) {
print "very new data", "\n";
next;
}
print;
}
print "more data", "\n";
тогда назовите это так: perl yourscript.pl inputfile > outputfile
Если вы хотите открыть файлы самостоятельно (Здесь мы просто пропустите ненужные строки):
my open $in_fh, '<', $inputfile
or die "Can't open file $inputfile: $!";
my open $out_fh, '>', $outputfile
or die "Can't open file $output: $!";
while (my $line = <$in_fh>) {
next if ( $. == 2 or $. == 3 or $. == 4 );
print $out_fh $line;
}
print $out_fh "...whatever\n";
Если вы открываете файл в добавить режим тогда вы не можете заменить строку, которая уже была в файле, когда вы его вскрывали. Добавить файл означает, что ваша программа имеет возможность только читать файл и добавлять его в конец.
вы можете создать новый файл, добавить в него содержимое (возможно, на основе содержимого из другого файла), а затем скопировать новый файл поверх другого файла.
думаю, я не совсем понимаю задание.
use File::Copy;
copy("/file1.txt","/file1_old.txt");
open(FILEHANDLE,">file1.txt");
open(FILEHANDLE1,"<file1_old.txt");
my $linecount=1;
while(<FILEHANDLE1>)
{
print $_."\n";
if($linecount>4)
{
print FILEHANDLE "$_";
}
$linecount++;
}
{
## new data will be placed
}
#####close the file handle
close(FILEHANDLE1);
close(FILEHANDLE);