OK、私は現時点でアクセスできないので、これは 100% またはコンパイルされることさえ保証されていませんが、十分なガイダンスを提供する必要があります:
解決策 1 : (語順は関係ありません)
#!/usr/bin/perl -w
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: $!";
これにより、B にある A の単語のみを含む新しいファイル「A_new」が作成されます。
これにはわずかなバグがあります。ファイル A 内の複数の空白が単一のスペースに置き換えられるため、
word1 word2 word3
となります
word1 word2 word3
修正することはできますが、そうするのは本当に面倒なので、空白を 100% 正しく保持することが絶対に必要でない限り、私は気にしませんでした。
解決策2:(語順は重要ですが、空白をまったく保持することなく、ファイルAから単語を出力できます)
#!/usr/bin/perl -w
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 が必要なのですか? :) )
これは、Perl を使用せずにシェルで簡単に実行できます (または、親 Perl スクリプトで system() 呼び出しまたはバッククォートを使用して)。
comm -12 A B | tr "\012" " "
これを Perl から呼び出すには:
my $new_text = `comm -12 A B | tr "\012" " " `;
しかし、これが「悪いPerl」と見なされる理由についての私の最後のコメントを参照してください...少なくとも、非常に多くのファイルが繰り返され、パフォーマンスを気にするループでこれを行う場合。