使用Perl,我想只打印每个列表中的重复(重复)值。值应至少出现2次(2次或更多次)。每个列表(行)应单独考虑。
例如,给定输入:
abc 51082 6457 31072 5575 5488 4842 16567 151
cde 5575 3674 8150 5575 3674 8150
fgh 5737 6887 48278 3674 34399 3674 8150
我想要以下输出:
abc
cde 5575 3674 8150
fgh 3674
我编写了以下源代码,但它没有提供正确的输出:
#!/usr/bin/perl -w
open FH, "input.txt";
@a=<FH>;
my %count_of;
foreach $tmp (@a)
{
foreach $word (split /\s/, $tmp)
{
$count_of{$word}++;
if ($count_of{$word} >=2)
{
print "$word\n";
}
}
}
exit;
有人可以指导我对代码需要进行哪些更改? 谢谢!
答案 0 :(得分:1)
这是一个工作版本。查看代码中的注释以了解更正
#!/usr/bin/perl
# always use strict and warnings: this will help you to find errors
use warnings;
use strict;
open FH, 'input.txt';
# always declare variables
my @a=<FH>;
# you should close file handles
close FH;
# declare $tmp
foreach my $tmp (@a) {
# you need to process the first element differently since you
# want to always print it
my @row = split /\s/, $tmp;
# you should check for empty rows
if (@row == 0) {
# empty row
next;
}
# removes the first element
my $header = shift @row;
# the first element is always printed
print $header;
# this should be local otherwise you are counting globally
# a new declaration will give you a new hash
my %count_of;
# declare $word
foreach my $word ( @row ) {
# you should not increment an undefined variable
if ( $count_of{$word} ) {
$count_of{$word} = 1;
} else {
$count_of{$word}++;
}
# just print the second time you see the word
if ( $count_of{$word} == 2) {
print " $word";
}
}
print "\n";
}
# it is good practice to return true at the end of a script (no need to exit)
1;
这会产生:
abc
cde 5575 3674 8150
fgh 3674
答案 1 :(得分:1)
grep
结合哈希来跟踪看到的值,非常适合这类问题:
#!/usr/bin/env perl
use strict;
use warnings;
my $file = "input.txt";
open my $fh, "<", "$file" or die "Unable to open $file: $!\n";
while (<$fh>) {
chomp;
my ($key, @values) = split or next; # skip empty rows
my (%seen, @dupl);
@dupl = grep $seen{$_}++ == 1, @values;
print "$key @dupl\n";
}
输出:
abc
cde 5575 3674 8150
fgh 3674
请注意,or
(与||
相对)在两种情况下都至关重要。此外,您应始终检查您尝试打开文件的结果use strict;
,并最好将-w
替换为use warnings;
以便移植。无论如何,当你要逐行处理它时,也没有必要啜饮你的文件。
答案 2 :(得分:0)
#!/usr/bin/perl -w
use strict;
while (<>) {
chomp;
my ($name, @inp) = split /\s+/ or next;
my %counts;
for (@inp) { $counts{$_}++ }
print join (' ', $name, map { $counts{$_} > 1 ? $_ : () } keys %counts), "\n";
}