如何通过perl或bash删除重复行?
我有一份清单:如何通过perl或bash删除重复行?,perl,bash,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 第一个sed使用制表符将电子邮件分
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
第一个sed使用制表符将电子邮件分为两个字段(名称+域),以便uniq在删除重复域时跳过第一个字段,最后一个sed删除制表符
#!/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
第一个sed使用制表符将电子邮件分为两个字段(名称+域),以便uniq在删除重复域时跳过第一个字段,最后一个sed删除制表符。#/usr/bin/env perl
#!/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
严格使用;使用警告;
使用电子邮件::地址;
我的%数据;
while(我的$line=){
我的($addr)=电子邮件::地址->解析($line=~/^(\S+/);
推送{$data{$addr->host},$addr->original;
}
对于我的$addrs(值%data){
如果(@$addrs>2){
打印“$addrs->[0]\n”;
}
否则{
为@$addrs打印“$\un”;
}
}
__资料__
asd@domain.com
fff@domain.com
yyy@domain.com
ttt@test.com
rrr@test.com
fff@test.com
yyy@my.com
yyy@my.com
#/usr/bin/env perl
严格使用;使用警告;
使用电子邮件::地址;
我的%数据;
while(我的$line=){
我的($addr)=电子邮件::地址->解析($line=~/^(\S+/);
推送{$data{$addr->host},$addr->original;
}
对于我的$addrs(值%data){
如果(@$addrs>2){
打印“$addrs->[0]\n”;
}
否则{
为@$addrs打印“$\un”;
}
}
__资料__
asd@domain.com
fff@domain.com
yyy@domain.com
ttt@test.com
rrr@test.com
fff@test.com
yyy@my.com
yyy@my.com
我不明白为什么示例输出包含yyy@my.com
两次,但假设这是一个错误
只要不存在尾随空格字符或更复杂形式的电子邮件地址的问题,就可以使用Perl简单地完成这项工作
perl -aF@ -ne 'print unless $seen{$F[1]}++' myfile
输出
asd@domain.com
ttt@test.com
yyy@my.com
我不明白为什么您的示例输出包含
yyy@my.com
两次,但假设这是一个错误
只要不存在尾随空格字符或更复杂形式的电子邮件地址的问题,就可以使用Perl简单地完成这项工作
perl -aF@ -ne 'print unless $seen{$F[1]}++' myfile
输出
asd@domain.com
ttt@test.com
yyy@my.com
这可能适合您:
sed ':a;$!N;s/^\([^@]*@\([^\n]*\)\)\n.*\2/\1/;ta;P;D' file
asd@domain.com
ttt@test.com
yyy@my.com
这可能适合您:
sed ':a;$!N;s/^\([^@]*@\([^\n]*\)\)\n.*\2/\1/;ta;P;D' file
asd@domain.com
ttt@test.com
yyy@my.com
如果您不介意顺序,只需使用排序:
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-
如果您不介意顺序,只需使用排序:
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-