如何在Perl中过滤或保留重复项?

时间:2010-05-07 09:49:59

标签: perl

我有一个文本字符串,它有一些重复的字符(FFGGHHJKL)。这些可以通过使用正向前瞻来实现:

$ perl -pe 's/(.)(?=.*?\1)//g']

例如,对于"FFEEDDCCGG",输出为"FEDCG"

我的问题是如何使它在数字上运作(例如212 212 43 43 5689 6689 5689 71 81 ===输出应该是212 43 5689 6689 71 81)?此外,如果我们想要只有重复记录作为具有n行

的文件的输出
212 212 43 43 5689 6689 5689 71 81
66 66 67 68 69 69 69 71 71 52
..

输出:

212 212 43 43 5689 5689
66 66 69 69 69 71 71

我该怎么做?

2 个答案:

答案 0 :(得分:2)

以下是未经测试的,但应仅打印出重复项。

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";

要删除重复项,您现在可以:

print "$_ " for keys %seen;

但不保留订单。你可以做类似的事情,就像我打印出来的那样。或者使用Tie::Hash::Indexed(感谢,daxim)或Tie::IxHash

等模块

答案 1 :(得分:0)

第一部分

$ 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

第二部分

$ 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