How do I filter or keep duplicates in Perl?
I have one text string that has multiple repeating characters (FFGGHHJKL). They can be made unique by using a positive result:
$ perl -pe 's/(.)(?=.*?\1)//g']
For example, when "FFEEDDCCGG"
outputting "FEDCG"
.
My question is how to make it work with numbers (example 212 212 43 43 5689 6689 5689 71 81 === the output should be 212 43 5689 6689 71 81)? Also, if we want as output from a file that has n lines
only duplicate entries were specified,212 212 43 43 5689 6689 5689 71 81 66 66 67 68 69 69 69 71 71 52 ..
Output:
212 212 43 43 5689 5689 66 66 69 69 69 71 71
How can i do this?
a source to share
The following is untested, but should only print duplicates.
my $line = "212 212 43 43 5689 6689 5689 71 81\n";
chomp $line;
my %seen;
my @order;
foreach my $elem (split /\s+/, $line) {
++$seen{$elem};
push @order, $elem if $seen{$elem} == 2;
}
foreach my $elem (@order) {
print "$elem " x $seen{$elem};
}
print "\n";
To remove duplicates, you can now:
print "$_ " for keys %seen;
BUT this does not preserve order. You can do something like this, as I did for printing out cheats only. Or use a module like Tie :: Hash :: Indexed (thanks, daxim) or Tie :: IxHash
a source to share
For the first part
$ cat prog.pl
#! /usr/bin/perl -lp
my %seen;
$_ = join " " => map $seen{$_}++ ? () : $_ => split;
$ echo 212 212 43 43 5689 6689 5689 71 81 | ./prog.pl
212 43 5689 6689 71 81
For the second part
$ cat prog.pl
#! /usr/bin/perl -lp
my %dups;
my @nums = split;
++$dups{$_} for @nums;
$_ = join " " => grep $dups{$_} > 1 => @nums;
$ cat input
212 212 43 43 5689 6689 5689 71 81
66 66 67 68 69 69 69 71 71 52
$ ./prog.pl input
212 212 43 43 5689 5689
66 66 69 69 69 71 71
a source to share