好的,我现在没有访问权限,所以不能保证这是100%的或者能够编译,但应该提供足够的指导:
解决方案1:(单词顺序无关紧要)
use strict;
use File::Slurp;
my @B_lines = File::Slurp::read_file("B") || die "Error reading B: $!";
my %B_words = ();
foreach my $line (@B_lines) {
map { $B_words{$_} = 1 } split(/\s+/, $line);
}
my @A_lines = File::Slurp::read_file("A") || die "Error reading A: $!";
my @new_lines = ();
foreach my $line (@A_lines) {
my @B_words_only = grep { $B_words{$_} } split(/\s+/, $line);
push @new_lines, join(" ", @B_words_only) . "\n";
}
File::Slurp::write_file("A_new", @new_lines) || die "Error writing A_new: $!";
这将创建一个新文件"A_new",其中仅包含在B中的A的单词。
这有一个小错误 - 它将用单个空格替换文件A中的任何多个空格,因此
word1 word2 word3
将变成
word1 word2 word3
它可以被修复,但将会非常麻烦,所以我没有费心,除非您绝对需要完全正确地保留空格
解决方案 2:(单词顺序很重要,但您可以毫不考虑地打印文件 A 中的单词,而不必考虑保留空格)
use strict;
use File::Slurp;
my @A_words = split(/\s+/gs, File::Slurp::read_file("A") || die "Error reading A:$!");
my @B_words = split(/\s+/gs, File::Slurp::read_file("B") || die "Error reading B:$!");
my $B_counter = 0;
for (my $A_counter = 0; $A_counter < scalar(@A_words); ++$A_counter) {
while ($B_counter < scalar(@B_words)
&& $B_words[$B_counter] ne $A_words[$A_counter]) {++$B_counter;}
last if $B_counter == scalar(@B_words);
print "$A_words[$A_counter]";
}
解决方案3(为什么我们还需要Perl呢?:)
你可以在shell中轻松地完成这个任务,无需使用Perl(或通过父Perl脚本中的system()调用或反引号)
comm -12 A B | tr "\012" " "
在 Perl 中调用此函数:
my $new_text = `comm -12 A B | tr "\012" " " `;
但请看我的最后一条评论,为什么这可能被认为是“糟糕的Perl”……至少如果您在循环中执行此操作,并且迭代了非常多的文件并关心性能。