0

我想从输入文件中删除与排除文件中列出的任何模式匹配的行。

输入文件非常大(~500 MB),所以我也在寻找有效的解决方案。

请注意,下面的示例只是一个示例,排除可能包含复杂的模式,包括特殊字符,例如/

包含排除列表的文件(例外

Jun
Jul
Aug

输入文件 ( infile )

Jan 02, 2013
Jul 02, 1988
Feb 02, 1988
Jun 02, 1988
Feb 02, 1988
Aug 02, 1988
Jan 02, 2013
Sep 02, 1988
Mar 02, 1988
Jun 02, 1988
Nov 02, 1988

期望的输出(outfile

Jan 02, 2013
Feb 02, 1988
Feb 02, 1988
Jan 02, 2013
Sep 02, 1988
Mar 02, 1988
Nov 02, 1988

我可以使用以下命令,给出排除列表,它工作正常。

egrep -v "Jun|Jul|Aug" infile > outfile

我的问题是如何|从异常文件中获取管道分隔的字符串并将其传递给上面的 grep 命令?或者有没有其他最佳方式来实现这一目标?

我必须将其作为解决方案的一部分来实现perl,在该解决方案中,进一步的处理是通过散列进行的。但我对任何 linux 解决方案持开放态度,因为我可以从我的 perl 脚本中执行这些命令。

您在这方面的帮助将不胜感激。

更新

同时人们正在帮助我解决他们的解决方案,我可以编写以下代码perl并且它也有效。

#!/usr/bin/perl
use warnings;
use strict;

open my $exfread, '<', "exception" or die $!;
chomp ( my @exclusions = <$exfread> );
close $exfread;
my $ex_str = join '|', @exclusions;
# print $ex_str . "\n";

open my $infread, '<', "infile" or die $!;
open my $outfwrite, '>', "outfile" or die $!;

while (<$infread>) {
    next if /${ex_str}/;    
    print $outfwrite $_;
    # do some more processing using hash
}

close $outfwrite;
close $infread;

我很想听听关于他们效率的不同方法的反馈。正如我之前提到的,由于我的输入文件很大并且文件数量也很大,所以我接下来要担心的是运行时间。

4

4 回答 4

4

该程序应该适合您的目的。exception.txt它的工作原理是通过将每一行与交替运算符连接起来,从 的内容中形成一个正则表达式|。然后正则表达式用qr.

这应该证明非常快,因为每行只执行一个正则表达式比较。

use strict;
use warnings;
use autodie;

my $regex = do {
  open my $in,  '<', 'exception.txt';
  my @infile = <$in>;
  chomp @infile;
  local $" = '|';
  qr/@infile/;
};

open my $in,  '<', 'infile.txt';
open my $out, '>', 'outfile.txt';

while (<$in>) {
  print $out $_ unless $_ =~ $regex;
}

输出

Jan 02, 2013
Feb 02, 1988
Feb 02, 1988
Jan 02, 2013
Sep 02, 1988
Mar 02, 1988
Nov 02, 1988
于 2013-10-09T21:01:03.907 回答
2

对于您的示例,此行有效:

grep -vf exception infile
于 2013-10-09T21:01:06.930 回答
1
grep -vf patternfile 

应该和unix命令一样。

于 2013-10-09T21:02:30.893 回答
0

与其去 Perl 之外,为什么不像这样在里面读取和过滤呢?

#!/usr/bin/env perl

use strict;
use warnings;

my $ifile = 'old.txt';
my $ofile = 'new.txt';

open (my $ifh, '<', $ifile) or die $!;
open (my $ofh, '>', $ofile) or die $!;

while (<$ifh>) {
    print $ofh $_ unless /^Jun|Jul|Aug/;
}

close ($ifh);
close ($ofh);
于 2013-10-09T20:51:12.153 回答