perl 比较两个文件并打印匹配的行

发布于 2024-11-26 23:15:02 字数 690 浏览 0 评论 0原文

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

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

I have this script which is compare 2 files and print out the diff result. now I want to change the script instead of print out the diff lines, i want to print the matching lines. and also to count how many time matched every time running the script. would you please any one can give me a suggestion. thanks!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

耳钉梦 2024-12-03 23:15:02
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 代替其中一个名称,以将其中一个文件与另一个文件进行比较。使用 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;
}
print OUTFILE $line if $results{$line} == 1;

This will print lines that occur only one time.

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

One small change (== to >), and it will now print lines that occur more than one time. That should print identical duplicate lines.

Oh, also if you want the count, simply do:

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

I wrote a more concise and more flexible version here. It takes optional filenames and prints to STDOUT.

You can put 0 in place of one of the names to compare one of the files against another. Use shell redirection to save it to a file.

Usage:

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

Code:

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;
}
是伱的 2024-12-03 23:15:02

这不是最干净的做事方式......但艰苦的工作已经完成。反转逻辑以使其打印所有内容除非$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";
}

This isn't the cleanest way to do things... but the hard work has been done. Reverse the logic to make it print everything unless $results{$line} == 1, or if $results{$line} != 1.

To add the count:

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

Alternatively, you could filter out the unwanted with a grep, avoiding the if condition totally:

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

    print OUTFILE "Count: $results{$line} - $line";
}
燕归巢 2024-12-03 23:15:02

尝试测试::差异。请参阅此处的代码示例以及输出的样子:

http://metacpan.org/pod/Test ::差异

Try Test::Differences. See here for code sample and how the output would look like:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文