Reputation: 131
Perl program to read from a file which contains different email IDs from different domains. And list the username by removing the domain part.
Example:
Input file will contain:
[email protected]
[email protected]
[email protected]
The output file should look like:
The domain gmail.com contains following userid:
abc
The domain yahoo.com contains following userid:
xyz
The domain test.com contains following userid:
pqr
I tried using the code but it is only separating domain and user name, but not listing user names according to domain name.
use strict;
print "Enter the file name where emailids of different domains are present\n";
my $file=<stdin>;
open(DATA, "$file") or die ("Could not open the file\n");
while(<DATA>){
my @field=split(/@/, "$_" );
chomp $_;
my $username=@field[0];
my $domain=@field[1];
print "The user id is $username \nThe domain name is $domain \n";
}
close (DATA);
Upvotes: 0
Views: 256
Reputation: 37
Try This
my $file=<stdin>;
my %hash;
open(DATA, "$file") or die ("Could not open the file\n");
while(<DATA>){
chomp($_);
my @field=split(/\@/, "$_" );
chomp(@fields);
push(@{$hash{$field[1]}},@field);
}
close (DATA);
you have all the domains in a hash and its user names as it value that is an array reference . you can either iterate it or use Dumper
Upvotes: 0
Reputation: 5619
To keep to the point, you want to to populate a hash of arrays instead of printing as you find the addresses:
my %domains;
while(<DATA>){
my @field=split(/@/, "$_" );
chomp $_;
my $username=$field[0];
my $domain=$field[1];
#print "The user id is $username \nThe domain name is $domain \n";
push @{$domains{$domain}}, $username;
}
close (DATA);
for my $domain (sort keys %domains) {
print "The domain gmail.com contains following userid:\n";
print "$_\n" for sort @{$domains{$domain}};
}
And to indulge in this-is-how-I'd-do-it:
#! /usr/bin/env perl
use common::sense;
use Email::Address;
use YAML 'Dump';
die "usage: $0 <file1> [<file2> ... <fileN>]\n" unless @ARGV;
# although <> reads STDIN in the absense of @ARGV,
# which is often what you want.
my %hosts;
while (<>) {
for (Email::Address->parse($_)) {
push @{$hosts{$_->host}}, $_->user
}
}
print Dump \%hosts;
Given a file named 'file', containing:
abc @gamil.com
abd @gamil.com
abe @gamil.com
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
This is the usage and output:
$ perl test
usage: test <file1> [<file2> ... <fileN>]
$ perl test file
---
gamil.com:
- abc
- abd
- abe
test.com:
- pqr
- pqs
- pqt
yahoo.com:
- xyz
- xy1
- xy2
YAML's readable and useful. Email::Address saves us trouble, now and in the future.
Upvotes: 1
Reputation: 116167
You have few mistakes in your code:
@
inside strings as \@
.@array
. But to address elements in array, you need to use $
: $array[0]
.This means, your code should look like this:
use strict;
print "Enter the file name where emailids of different domains are present\n";
my $file=<stdin>;
open DATA, "$file" or die $!;
while (my $line = <DATA>) {
chomp $line;
my ($username, $domain) = split /\@/, $line;
print "The user id is $username \nThe domain name is $domain \n";
}
close DATA;
I have simplified few things, like use $line
instead of $_
to make it more clear, and to save results of split into variables right away, rather than creating extra array.
Upvotes: 0