Perl сравнивает два файла и печатает соответствующие строки - PullRequest
2 голосов
/ 28 июля 2011

У меня есть этот скрипт, который сравнивает 2 файла и распечатывает результат сравнения. Теперь я хочу изменить скрипт вместо того, чтобы распечатывать строки различий, я хочу напечатать совпадающие строки. а также посчитать, сколько времени совпало при каждом запуске скрипта. пожалуйста, кто-нибудь может дать мне предложение. спасибо!

#! /usr/local/bin/perl 
# compare 
my $f1 = "/opt/test.txt";
my $f2 = "/opt/test1.txt";
my $outfile = "/opt/final_result.txt";
my %results = (); 
open FILE1, "$f1" or die "Could not open file: $! \n";
while(my $line = <FILE1>){   $results{$line}=1;
}
close(FILE1); 
open FILE2, "$f2" or die "Could not open file: $! \n";
while(my $line =<FILE2>) {  
$results{$line}++;
}
close(FILE2);  
open (OUTFILE, ">$outfile") or die "Cannot open $outfile for writing \n";
foreach my $line (keys %results) { print OUTFILE $line if $results{$line} == 1;
}
close OUTFILE;

Ответы [ 3 ]

2 голосов
/ 28 июля 2011
print OUTFILE $line if $results{$line} == 1;

Это будет печатать строки, которые встречаются только один раз.

print OUTFILE $line if $results{$line} > 1;

Одно небольшое изменение (== до >), и теперь будет печатать строки, которые встречаются более одного раза,Это должно вывести одинаковые повторяющиеся строки.

О, также, если вы хотите подсчитать, просто сделайте:

if ( $results{$line} > 1 ) {
    print OUTFILE "$results{$line}: ", $line;
}

Я написал здесь более краткую и более гибкую версию.Он принимает необязательные имена файлов и печатает в STDOUT.

Вы можете поставить 0 вместо одного из имен, чтобы сравнить один из файлов с другим.Используйте перенаправление оболочки для сохранения в файл.

Использование:

$ script.pl file1.txt file2.txt > outfile.txt

Код:

use strict;
use warnings;
use autodie;

my $f1 = shift || "/opt/test.txt";
my $f2 = shift || "/opt/test1.txt";
my %results;
open my $file1, '<', $f1;
while (my $line = <$file1>) { $results{$line} = 1 }
open my $file2, '<', $f2;
while (my $line = <$file2>) { $results{$line}++ }
foreach my $line (sort { $results{$b} <=> $results{$a} } keys %results) {
    print "$results{$line}: ", $line if $results{$line} > 1;
}
1 голос
/ 28 июля 2011

Это не самый чистый способ сделать что-то ... но тяжелая работа была проделана.Измените логику, чтобы заставить ее печатать все unless $results{$line} == 1 или if $results{$line} != 1.

Чтобы добавить счетчик:

print OUTFILE "Count: $results{$line} - $line" if $results{$line} != 1;

В качестве альтернативы, вы можете отфильтровать ненужное с помощью grep, полностью избегая условия if:

foreach my $line ( grep { $results{$_} != 1 } keys %results ) {

    print OUTFILE "Count: $results{$line} - $line";
}
0 голосов
/ 29 июля 2011

Попробуйте Test :: Differences. Смотрите здесь пример кода и как будет выглядеть вывод:

http://metacpan.org/pod/Test::Differences

...