Как с помощью Perl фильтровать адреса электронной почты, принадлежащие определенному домену?

Как я могу просканировать файл, содержащий адреса электронной почты, разделенные символом новой строки, и избавиться от тех, которые принадлежат определенному домену, например. [email protected]. Я хочу избавиться от всех адресов электронной почты, которые @bad.com


person John    schedule 28.12.2009    source источник


Ответы (7)


Используйте grep вместо Perl

grep -v '@bad\.com' inputfile > outputfile

В Windows

findstr /v "@bad\.com" inputfile > outputfile
person Jim Garrison    schedule 28.12.2009
comment
а как насчет меня@bad.com.*? Также должны быть отфильтрованы? - person Leonardo Herrera; 29.12.2009

Email::Address — хороший модуль для работы с адресами электронной почты.

Вот пример, который может подогреть ваш аппетит:

use Email::Address;

my $data = 'this person email is [email protected]
blah blah [email protected] blah blah
[email protected]
';

my @emails      = Email::Address->parse( $data );
my @good_emails = grep { $_->host ne 'bad.com' } @emails;

say "@emails";       # => [email protected] [email protected] [email protected]
say "@good_emails";  # => [email protected]
person draegtun    schedule 29.12.2009

Это должно сделать:

$badDomain = "bad.com";
while(<>)
{
        s{\s+$}{};
        print "$_\n" if(!/\@$badDomain$/);
}
person codaddict    schedule 28.12.2009
comment
Поскольку мы никогда не использовали chomp() для строки, она уже будет иметь новую строку в конце по умолчанию. Вам не нужно печатать его с другим (если, конечно, вы не хотите, чтобы между строками вывода были пустые строки). - person Chris Lutz; 29.12.2009
comment
@Chris: Если вы внимательно посмотрите на строку 4, я удаляю все пробелы в конце. Это также удалит конечный \n. Поэтому \n в печати необходим. - person codaddict; 29.12.2009
comment
Ах. В таком случае, почему бы не s/\s+$/\n/; сохранить новую строку, а только print if /regex/ ? - person Chris Lutz; 29.12.2009

Следующее позволит вам иметь сценарий, который вы можете улучшить со временем... Вместо того, чтобы просто отфильтровывать @bad.com (что вы можете сделать с помощью простого grep), вы можете написать свой сценарий, чтобы вы могли легко усложнить, какие домены являются нежелательными.

my $bad_addresses = {'bad.com'=>1};

while (my $s = <>) {
    print $s unless (is_bad_address($s));
}

sub is_bad_address {
    my ($addr) = @_;
    if ($addr=~/^([^@]+)\@([^@\n\r]+)$/o) {
        my $domain = lc($2);
        return 0 unless (defined $bad_addresses->{$domain});
        return $bad_addresses->{$domain};
    }
    return 1;
}
person Zoran Simic    schedule 29.12.2009

Не слишком отличается от того, что сделали другие.

use strict;
use warnings;

my @re = map { qr/@(.*\.)*\Q$_\E$/ } qw(bad.com mean.com);

while (my $line = <DATA>) {
    chomp $line;
    if (grep { $line =~ /$_/ } @re) {
        print "Rejected: $line\n";
    } else {
        print "Allowed: $line\n";
    }
}

__DATA__
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
person Leonardo Herrera    schedule 29.12.2009

Перл

perl -ne 'print if !/@bad\.com/' file

аук

awk '!/@bad\.com/' file 
person ghostdog74    schedule 28.12.2009
comment
Это не правильный шаблон. Это также исключает notbad.com и т. д. - person brian d foy; 29.12.2009

этот код должен отфильтровать все адреса @bad.com из входных файлов.

 my @array = <>;

 foreach(@array) {
   if(!/\@bad.com$/) {
     print $_;
   }
 }
person dan    schedule 28.12.2009
comment
Это ужасно. Зачем вам <>, когда вы можете просто перебрать его для того же эффекта, почти без влияния на память? - person Chris Lutz; 29.12.2009