如何通过perl或bash删除重复的行?

时间:2012-04-08 19:36:01

标签: perl bash

我有一个清单:

asd@domain.com
fff@domain.com
yyy@domain.com
ttt@test.com
rrr@test.com
fff@test.com
yyy@my.com
yyy@my.com

如何做到这一点:

如果在整个列表中我们看到三个或更多具有相同域名的电子邮件 - 除了第一个需要删除之外的所有重复项。

Output:

asd@domain.com
ttt@test.com
yyy@my.com
yyy@my.com

5 个答案:

答案 0 :(得分:3)

#!/usr/bin/env perl

use strict; use warnings;
use Email::Address;

my %data;

while (my $line = <DATA>) {
    my ($addr) = Email::Address->parse($line =~ /^(\S+)/);
    push @{ $data{ $addr->host } }, $addr->original;
}

for my $addrs (values %data) {
    if (@$addrs > 2) {
        print "$addrs->[0]\n";
    }
    else {
        print "$_\n" for @$addrs;
    }
}

__DATA__
asd@domain.com
fff@domain.com
yyy@domain.com
ttt@test.com
rrr@test.com
fff@test.com
yyy@my.com
yyy@my.com

答案 1 :(得分:1)

 sed -s 's/@/@\t/g' test.txt | uniq -f 1 | sed -s 's/@\t/@/g'

第一个sed将2个字段(名称+域)中的电子邮件与制表符分隔开,以便uniq可以在删除重复的域时跳过第一个字段,最后一个sed将删除该选项卡。

答案 2 :(得分:0)

我很困惑为什么你的示例输出包含yyy@my.com两次但是假设它是错误的。

只要尾随空格字符或更复杂形式的电子邮件地址没有问题,您只需在Perl中执行此操作

perl -aF@ -ne 'print unless $seen{$F[1]}++' myfile

<强>输出

asd@domain.com
ttt@test.com
yyy@my.com

答案 3 :(得分:0)

这可能对您有用:

sed ':a;$!N;s/^\([^@]*@\([^\n]*\)\)\n.*\2/\1/;ta;P;D' file
asd@domain.com
ttt@test.com
yyy@my.com

答案 4 :(得分:0)

如果您不介意订单,只需使用sort:

sort -t '@' -u -k 2,2 your_file

如果您注意订单,请执行

gawk '{print NR "@" $0}' your_file | sort -t '@' -u -k 3,3 | sort -t '@' -k 1,1n | cut -d \@ -f 2-