我正在寻找一种方法来读取输入文件并仅在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);
提前致谢!
答案 0 :(得分:8)
这是循环播放行的更好方法。它可以避免一次将整个输入文件加载到内存中:
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;
答案 1 :(得分:3)
样式提示:
open
close
的结果见下文:
#! /usr/bin/perl
use warnings;
use strict;
die "Usage: $0 old new\n" unless @ARGV == 2;
my($csvfile,$csvnewfile) = @ARGV;
open my $in, "<", $csvfile or die "$0: open $csvfile: $!";
open my $out, ">", $csvnewfile or die "$0: open $csvnewfile: $!";
while (<$in>) {
print $out $_ if /^\w{4}\.\w{4}\.\w{4}/;
}
close $out or warn "$0: close $csvnewfile: $!";
答案 2 :(得分:2)
使用grep
grep "^\w\{4\}\.\w\{4\}\.\w\{4\}\b" file
答案 3 :(得分:1)
if ($_ =~ m/^\w{4}\.\w{4}\.\w{4}/i)
我认为。我的perl有点生疏。
答案 4 :(得分:1)
从perlfaq5回答How do I change, delete, or insert a line in a file, or append to the beginning of a file?
从文本文件中插入,更改或删除行的基本思想包括读取和打印文件到要进行更改的位置,进行更改,然后读取和打印文件的其余部分。 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 $_;
}
要跳过行,请使用循环控件。此示例中的下一个跳过注释行,最后一个在遇到 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 $_;
}
如果由于一些奇怪的原因,你真的想要一次看到整个文件而不是逐行处理,你可以把它捏进去(只要你能把整个文件放在内存中!):< / p>
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单行来就地修改文件。以下内容将inFile.txt中的所有'Fred'更改为'Barney',并使用新内容覆盖文件。使用-p开关,Perl在您使用-e指定的代码周围环绕一个while循环,-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,除了它在循环结束时不打印$ _,所以你必须自己做。在这种情况下,首先打印$ _,然后打印要添加的行。
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
答案 5 :(得分:0)
如果您不介意将其保留为命令行1衬垫:
perl -ne "print if /^.{4}[.].{4}[.].{4}/" csvfile.csv > csvnewfile.csv
答案 6 :(得分:0)
perl -ne 'print if /^\w{4}\.\w{4}\.\w{4}\b/' file > newfile.csv