1

我有一个清单:

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
4

5 回答 5

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
于 2012-04-08T20:10:48.443 回答
1
 sed -s 's/@/@\t/g' test.txt | uniq -f 1 | sed -s 's/@\t/@/g'

第一个 sed 用制表符将电子邮件分隔为 2 个字段(名称 + 域),以便 uniq 在删除重复域时可以跳过第一个字段,最后一个 sed 删除制表符。

于 2012-04-08T19:45:31.163 回答
0

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

只要尾随空格字符或更复杂形式的电子邮件地址没有问题,您就可以在 Perl 中简单地使用

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

输出

asd@domain.com
ttt@test.com
yyy@my.com
于 2012-04-08T21:26:22.317 回答
0

这可能对您有用:

sed ':a;$!N;s/^\([^@]*@\([^\n]*\)\)\n.*\2/\1/;ta;P;D' file
asd@domain.com
ttt@test.com
yyy@my.com
于 2012-04-09T00:31:12.857 回答
0

如果您不介意顺序,只需使用排序:

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-
于 2012-04-09T10:19:22.967 回答