我有一个大文本文件,它是一个电子邮件列表(每个后跟一个/ n)。
我想运行一个perl命令,根据电子邮件是否包含某个字符串来生成包含不同列表的文件。
到目前为止,我有:
perl -wne'
while (/[\w\.\-]+@[\w\.\-]+\w+/g) {
print if "$&\n /gmail/;
}
' all_emails_extracted.csv | sort -u > output.txt
如果它包含'gmail',它应该编写电子邮件,但无论我如何构建{print if}
周围的区域,我都会收到语法错误答案 0 :(得分:4)
通常是
print "$&\n";
因此,如果添加一个语句修饰符,它将变为
print "$&\n" if /gmail/;
您错过了引用("
),而您的if
错位。
更简单一点:
perl -nE'say grep /gmail/, /[\w\.\-]+@[\w\.\-]+\w+/g'
你甚至可以在Perl中进行重复数据删除。
perl -MList::MoreUtils=uniq -nE'say uniq grep /gmail/, /[\w\.\-]+@[\w\.\-]+\w+/g'
答案 1 :(得分:2)
你明显过于复杂......
perl -wne'print if /@.*gmail/' all_emails_extracted.csv
或者,更简单(但没有Perl):
grep @.*gmail all_emails_extracted.csv
答案 2 :(得分:0)
您的代码中已经指出了错误,所以这是另一个建议:使用Email::Address:
$ cat addresses
bob@gmail.com
bob@yahoo.com
bobette@springfield-amusement-park.com
bobbyMcBobberson@springfield-amusement-park.com
bahb@yahoo.com
bob @ yahoo.com
bob @ springfield-amusement-park.com
postmaster@hotmail.com
$ perl -MEmail::Address -lne 'for (Email::Address->parse($_)) { $bobs{$_->format}++ if $_->user =~ /bob/i } END { print for sort keys %bobs }' addresses
bob@gmail.com
bob@springfield-amusement-park.com
bob@yahoo.com
bobbyMcBobberson@springfield-amusement-park.com
bobette@springfield-amusement-park.com
你说你想“制作不同列表的文件”?电子邮件::地址也可以提供帮助:
while (<DATA>) {
for (Email::Address->parse($_)) {
push @{$categories{by_host}{$_->host}}, $_;
push @{$categories{bobs}}, $_ if $_->user =~ /bob/i
}
}
然后,这将在以每个地址的主机名命名的文件中创建用户名列表:
for my $host (keys $categories{by_host}) {
open my $hf, '>', "hosts.$host" or die $!;
for (@{$categories{by_host}{$host}}) {
print {$hf} $_->user, "\n"
}
close $hf
}
所以,在最后一个列表上运行:
$ cat hosts.springfield-amusement-park.com
bobette
bobbyMcBobberson
bob
$ cat hosts.yahoo.com
bob
bahb
bob