Как я могу написать только определенные строки файла в Perl?
Я ищу способ прочитать входной файл и распечатать только выделенные строки в выходной файл в Perl. Строки, которые я хочу напечатать в выходной файл, начинаются с xxxx.xxxx.xxxx
, где x
- буквенно-цифровой символ (периоды-это периоды, а не подстановочные знаки). Не все строки имеют одинаковое окончание, если это имеет значение. Я думаю что-то вроде следующего (состояние if
утверждение, что на самом деле, насколько я могу рассказывать.)
open(IN, "<$csvfile");
my @LINES = <IN>;
close(IN);
open(OUT, ">$csvnewfile");
print OUT @LINES if ([line starts with xxxx.xxxx.xxxx]);
close(OUT);
спасибо заранее!
7 ответов
вот лучший способ, чтобы петля через ваши линии. Это позволяет избежать загрузки всего входного файла в память сразу:
use strict;
use warnings;
open my $fhi, '<', $csvfile or die "Can not open file $csvfile: $!";
open my $fho, '>', $csvnewfile or die "Can not open file $csvnewfile: $!";
while (<$fhi>) {
print $fho $_ if m/^ \w{4} \. \w{4} \. \w{4} /x;
}
close $fho;
close $fhi;
имейте в виду, что \w
класс символов также включает символы подчеркивания. Чтобы избежать подчеркивания:
print $fho $_ if m/^ [a-z\d]{4} \. [a-z\d]{4} \. [a-z\d]{4} /xi;
модные советы:
- использовать лексические filehandles
- проверяем результат
open
- также хорошая идея, чтобы проверить результат
close
на ручке, открытой для записи
см. ниже:
#! /usr/bin/perl
use warnings;
use strict;
die "Usage: old new\n" unless @ARGV == 2;
my($csvfile,$csvnewfile) = @ARGV;
open my $in, "<", $csvfile or die ": open $csvfile: $!";
open my $out, ">", $csvnewfile or die ": open $csvnewfile: $!";
while (<$in>) {
print $out $_ if /^\w{4}\.\w{4}\.\w{4}/;
}
close $out or warn ": close $csvnewfile: $!";
С 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 $_;
}
закрыть $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 $_;
}
закрыть $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 $_;
}
закрыть $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 $_;
}
чтобы пропустить строки, используйте элементы управления циклом. Следующий в этом примере пропускает строки комментариев, а последний останавливает всю обработку, как только он встречает либо конец или сведения.
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
сделать резервное копирование файлов.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
... or ...
perl -pi -e 'next unless /d/' inFile.txt
Если вы не против оставить его в качестве командной строки 1 вкладыш:
perl -ne "print if /^.{4}[.].{4}[.].{4}/" csvfile.csv > csvnewfile.csv