我想删除以HPL_开头的文本文件中的所有行我已经实现了这个并且可以打印到屏幕,但是当我尝试写入文件时,我只是将修改后的文本的最后一行打印在新文件。请帮忙!
open(FILE,"<myfile.txt");
@LINES = <FILE>;
close(FILE);
open(FILE,">myfile.txt");
foreach $LINE (@LINES) {
@array = split(/\:/,$LINE);
my $file = "changed";
open OUTFILE, ">$file" or die "unable to open $file $!";
print OUTFILE $LINE unless ($array[0] eq "HPL_");
}
close(FILE);
close (OUTFILE);
exit;
答案 0 :(得分:7)
您只想删除所有以HPL_
开头的行?这很简单!
perl -pi -e 's/^HPL_.*//s' myfile.txt
是的,它真的只是一个单行。 : - )
答案 1 :(得分:4)
如果您不想使用单行,请按如下方式重写“写入文件”部分:
my $file = "changed";
open( my $outfh, '>', $file ) or die "Could not open file $file: $!\n";
foreach my $LINE (@LINES) {
my @array = split(/:/,$LINE);
next if $array[0] eq 'HPL_';
print $outfh $LINE;
}
close( $outfh );
请注意每次循环时{j}文件open()
。这导致文件仅包含最后一行,因为open()
使用>
表示“覆盖文件中的内容”。这是您的代码的主要问题。
修改:除此之外,您要清理代码。正如我所示,使用词法文件句柄。始终在每个Perl程序的顶部添加tchrist发布的三行。使用open()
的三运营商版本。不要将整个文件粘贴到一个数组中,就像你试图读取一个巨大的文件一样,它可能会导致你的计算机内存不足。您的程序可以重写为:
#!perl
use strict;
use autodie;
use warnings FATAL => "all";
my $infile = "myfile.txt";
my $outfile = "changed.txt";
open( my $infh, '<', $infile );
open( my $outfh, '>', $outfile );
while( my $line = <$infh> ) {
next if $line =~ /^HPL_/;
print $outfh $line;
}
close( $outfh );
close( $infh );
请注意use autodie
如何or die ...
无需向open()
函数添加autodie
,因为{{1}} pragma会为您处理。{/ p>
答案 2 :(得分:4)
您的代码存在的问题是,在您的行处理循环中打开文件输出,由于您使用了'&gt;'打开的形式,每次打开文件进行写入,删除任何以前的内容。
将open()的调用移到文件的顶部,在循环上方,它应该可以工作。
另外,我不确定你的意图,但是在你的例子的第4行,你重新打开你的输入文件进行写入(使用'&gt;'),这也会破坏它所包含的任何内容。
作为旁注,您可以尝试阅读Perl的grep()命令,该命令旨在完全满足您的需求,如:
#!/usr/bin/perl
use strict;
use warnings;
open(my $in, '<', 'myfile.txt') or die "failed to open input for read: $!";
my @lines = <$in> or die 'no lines to read from input';
close($in);
# collect all lines that do not begin with HPL_ into @result
my @result = grep ! /^HPL_/, @lines;
open(my $out, '>', 'changed.txt') or die "failed to open output for write: $!";
print { $out } @result;
close($out);