【问题标题】:perl compare two file and print the matching linesperl 比较两个文件并打印匹配的行
【发布时间】:2011-07-28 16:04:26
【问题描述】:

我有这个脚本,它比较两个文件并打印出差异结果。现在我想更改脚本而不是打印出差异行,我想打印匹配的行。并计算每次运行脚本时匹配的时间。请问有人可以给我一个建议吗?谢谢!

#! /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;

【问题讨论】:

    标签: perl perl-module


    【解决方案1】:
    print OUTFILE $line if $results{$line} == 1;
    

    这将打印只出现一次的行。

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

    一个小改动(==&gt;),现在它将打印出现多次的行。那应该打印相同的重复行。

    哦,如果您想要计数,只需执行以下操作:

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

    我在这里写了一个更简洁、更灵活的版本。它采用可选文件名并打印到 STDOUT。

    您可以用0 代替其中一个名称,以将其中一个文件与另一个文件进行比较。使用 shell 重定向将其保存到文件中。

    用法:

    $ 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 个数字。因此,如果我在该行旁边看到“4”,则表示 4 周后表示该设备存在 4 周,如果第二行匹配 3 次,则表示该设备存在 3 周,依此类推。只是我的目标是知道每台设备匹配了多少周。
    • 我不太确定你在这里问什么以及它与你已有的有什么不同。一般来说,最好在 * 上一次询问所有目标,而不是试图将解决方案一块一块地拼凑在一起。我认为您的要求需要一个新问题,最好有一些示例输入/输出。
    • 解决方案上的计数器显示匹配的项目数量我的目标是匹配多长时间的计数器。即使我确实运行了脚本 10 次,您的解决方案上的计数器也会显示“2”。我的期望是显示“10”,因为脚本运行了 10 次并与当前列表匹配。很抱歉造成混乱,但这是我最初的目标,我没有添加新目标。英语也是我的第三语言,所以请考虑一下!
    【解决方案2】:

    这不是最干净的做事方式……但已经完成了艰苦的工作。反转逻辑使其打印所有unless $results{$line} == 1if $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";
    }
    

    【讨论】:

    • 非常感谢您的回答太完整了我的主要目标,但不是第二个目标。我想我不够清楚。对此感到抱歉。我希望柜台告诉我他们匹配了多少次。例子。该脚本每周运行一次,因此计数器每次运行都会添加 1 个数字。因此,如果我在该行旁边看到“4”,则表示 4 周后表示该设备存在 4 周,如果第二行匹配 3 次,则表示该设备存在 3 周,依此类推。只是我的目标是知道每台设备匹配了多少周。
    【解决方案3】:

    试试 Test::Differences。有关代码示例以及输出的外观,请参见此处:

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

    【讨论】:

      最近更新 更多