I got an array of email addresses:

@emails = ("sam\@email.com", "john\@email.com", "jenifer\@email.com");

There are 20 txt files wherefrom email addresses are being parsed. The parsed email addresses should be added to the @emails array only if they are not in it.

Example txt file contents:
===========================

Zip_Name: jenni@email.com
Zip_Name: sam@email.com
Zip_Name: dave@email.com
Zip_Name: john@email.com

Can it be done in a one-liner (checking and adding non existant array element)

My current code is following, and its not good becasue its adding the new e-mail address even if it is there already.

#READ FILE LIST                                     
foreach my $FILES (@FILES) {                        
		my $file=$FILES;                                
    open(INFO,"$dir\\$file");                       
    my @lines=<INFO>;                               
    foreach my $line (@lines)                       
    {                                               
    	if ($line =~ /^email/){                       
    		($line =~ s/email.//);                      
    		chomp $line;                                
    		if ($line =~ /^(\w|\-|\_|\.)+\@email\.com$/)
    			push (@emails, $line);                    
					}                                         
					else {                                    
						print "e-mail $line in file \"$file\" is
					}                                         
    	}         
         # email addresses come after "Zip_Name:" tag in those   files                            
    	if ($line =~ /^Zip_Name\:(.*)/){              
    			push (@sources, "$1");    		            
    		}                                           
    	                                              
    }                                               
  }

I don't know how to do it with a one-liner.

The "add only if not already present" requirement is much more easily done by building a hash instead of an array.

#!/usr/bin/perl
use strict;
use warnings;
use 5.010;

my %emails = ('sam@email.com' => undef,
              'john@email.com' => undef,
              'jenifer@email.com' => undef);#Hash of emails

while (<DATA>){
    chomp;
    s/^Zip_Name: //;#Remove unwanted text at beginning of $_ (default record variable)
    $emails{$_} = undef; #Email as key in hash automatically unique.
}

say "Hash contains the following emails:";
say foreach (sort keys %emails);

__DATA__
Zip_Name: jenni@email.com
Zip_Name: sam@email.com
Zip_Name: dave@email.com
Zip_Name: john@email.com

This gives the following output:

Hash contains the following emails:
dave@email.com
jenifer@email.com
jenni@email.com
john@email.com
sam@email.com
perl -ne 'BEGIN{%email=qw(sam@email.com 1 john@email.com 1 jenifer@email.com 1 );} 
          /Zip_Name:\s*(.*)/;   $email{$1}=1; 
          END{print "$_:$email{$_}\n" for sort keys %email;}
         ' input_file

Note : The above code tested at linux.

Edited 5 Years Ago by k_manimuthu: n/a

Comments
Looks good to me (Linux also)

Hmm...
How to test this code?
What is the input file here?

There are 20 txt files wherefrom email addresses are being parsed.

insist of "input_file" mentioned your ".txt" file.

Edited 5 Years Ago by k_manimuthu: n/a

Hi Muthu,
I could not run it on my windows machine properly.

From Google I found the following references which seems to works, (not 1-liner though)

my %k;
my @def_emails = ("sam@email.com", "john@email.com", "jenifer@email.com");
my @r_emails = ("array of emails parsed from the txt files");

map { $k{$_} = 1 } @r_emails;
# merging the elements, only unique emails are pushed
push(@r_emails, grep { !exists $k{$_} } @def_emails);

Perl one liner scripts single quotes and double quotes may varied linux and windows. Below I modified the code that works at windows.

perl -nle [B]"[/B]BEGIN{%email=qw(sam@email.com 1 john@email.com 1 jenifer@email.com 1 );} /Zip_Name:\s*(.*)/; $email{$1}=1; END{print $_ for sort keys %email[B]"[/B] input_file

Edited 5 Years Ago by k_manimuthu: n/a

Yes, it works now for me as well.
Thanks Muthu.

BR. Boshu

This question has already been answered. Start a new discussion instead.