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?

+2


a source to share


2 answers


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

+2


a source


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

      

0


a source







All Articles