1

我有一个大文本文件,它是一个电子邮件列表(每个都跟一个 /n)。

我想运行一个 perl 命令来根据电子邮件是否包含某个字符串来制作具有不同列表的文件。

到目前为止,我有:

 perl -wne'
    while (/[\w\.\-]+@[\w\.\-]+\w+/g) {
       print if "$&\n /gmail/;
    }
 ' all_emails_extracted.csv | sort -u > output.txt

如果它包含“gmail”,这应该写电子邮件,但无论我如何构建 {print if} 周围的区域,我都会收到语法错误

4

3 回答 3

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'
于 2013-06-01T17:56:18.723 回答
2

你已经大大地复杂化了......

perl -wne'print if /@.*gmail/' all_emails_extracted.csv

或者,更简单(但没有 Perl):

grep @.*gmail all_emails_extracted.csv
于 2013-06-01T17:11:46.480 回答
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

您说您想“制作具有不同列表的文件”?Email::Address 也可以提供帮助:

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
于 2013-06-02T03:52:38.030 回答