我有一个包含~175M行(large.csv)的CSV文件和另一个包含~50行(small.csv)的CSV文件。我必须通过large.csv直到找到包含small.csv中第一行的行并删除该行。从那里开始,我需要找到一行包含small.csv中的第二行并删除它,依此类推,直到我到达small.csv的末尾(所有行将按照它们现在的顺序进行匹配)。
这是我能够放在一起但我刚刚收回原始文件:
use strict;
use warnings;
use File::Copy;
my $delete = 'small.csv';
my $file = 'large.csv';
my $backup = "$file.bak";
copy $file, $backup or die "Copy failed: $!";
open my $in_dh, '<', $delete or die "$delete: $!";
open my $in_fh, '<', $backup or die "$backup: $!";
open my $out_fh, '>', $file or die "$file: $!";
my $match = <$in_dh>;
while (my $line = <$in_fh>) {
if (index ($line, $match) == -1) {
print $out_fh $line;
} else {
$match = <$in_dh>;
}
}
close $in_dh;
close $in_fh;
close $out_fh;
答案 0 :(得分:1)
你不要chomp
以$match
结尾的行,所以除非匹配在一行的末尾,否则它将会失败。在阅读small.csv
时,您也不会检查是否点击了EOF。
由于您的第一个文件较小,因此最简单的方法是将其加载到数组中。以下程序执行此操作,并使用$^I
和<>
来处理文件的就地编辑:
use strict;
use warnings;
use 5.010;
my @needles;
while (<>) {
chomp;
push @needles, $_;
last if eof;
}
{
local $^I = '.bak';
my $needle = shift @needles;
while (<>) {
chomp;
if (! defined $needle or index($_, $needle) == -1) {
say;
}
else {
$needle = shift @needles;
}
}
}
这样称呼:
/path/to/script needles haystack
其中needles
是包含要搜索的字符串的文件,haystack
是要搜索的文件。