Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Need help on writing loop.

Status
Not open for further replies.

linkexchange

Programmer
Dec 22, 2008
4
US
Hi! I'm not a professional programmer in perl, but I can write a little bit! I'd like to get this loop working right.

I have 2 files, one is just a sorted list of email addresses. The other contains another list with 9 columns and column 9 has the email address in it. I ran every email in the big list through an email verifier program and the email list is the results from that program. It's reduced down quite a bit. So now I need to write out a new file and compare each email in the email list to the email in the big file. For each email in the email list I need to print out certain columns in the big file. If an email in the big file doesn't match the current email, you skip it so that I have rows with valid email addresses. This is the part I'm not doing right in my loop.

#!/usr/bin/perl
my $emailurl="EMail.txt";
my $path="C:1millrealtors/";
my $outfile="fileout.txt";
my @newurl='';
##########################################################

# open file of emails
open(OUT,">$path$outfile") || die ("Can't open file!");
open(FILE,"1millrealtors/emails.txt") || die ("Can't open file!");
my @emailfile =<FILE>;
close FILE;

# open complete file
open(FILE,"./1millrealtors/CA154135.csv") || die ("Can't open file!");
my @bigfile =<FILE>;
close FILE;
print "Content-type: text/html\n\n";
my $j=0;
for(@emailfile) {
chomp;
for(@bigfile) {
chomp;
my @bigfilerow=split(',',$_);
# print $bigfilerow[9];
#exit;
if ($bigfilerow[9] eq $emailfile[0]) {
#print OUT bigfile[0] . "," . bigfile[1];
print $bigfilerow[0] . "," . $bigfilerow[8] . "," . $bigfilerow[9] . "\n" ;
last;} else {
next; }
}
}

 
Is it possible to provide example data for the 2 input files and the 1 output file (expected result)?

Chris
 
I'm not quite sure what's going on in that loop there, but see if this helps.
Code:
[url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url] FILE, [red]"[/red][purple]< emails.txt[/purple][red]"[/red] or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]Cannot open emails.txt[purple][b]\n[/b][/purple][blue]$![/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]%emails[/blue] = [url=http://perldoc.perl.org/functions/map.html][black][b]map[/b][/black][/url] [red]{[/red][url=http://perldoc.perl.org/functions/chomp.html][black][b]chomp[/b][/black][/url][red];[/red] [blue]$_[/blue],[fuchsia]1[/fuchsia][red]}[/red] [url=http://perldoc.perl.org/functions/grep.html][black][b]grep[/b][/black][/url] [red]{[/red][blue]$_[/blue] !~ [red]/[/red][purple]^[purple][b]\s[/b][/purple]*$[/purple][red]/[/red][red]}[/red] <FILE>[red];[/red]

[black][b]open[/b][/black] FILE, [red]"[/red][purple]< list.txt[/purple][red]"[/red] or [black][b]die[/b][/black] [red]"[/red][purple]Cannot open list.txt[purple][b]\n[/b][/purple][blue]$![/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
[black][b]open[/b][/black] OUT, [red]"[/red][purple]> output.txt[/purple][red]"[/red] or [black][b]die[/b][/black] [red]"[/red][purple]Cannot create output.txt[purple][b]\n[/b][/purple][blue]$![/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]

[olive][b]while[/b][/olive] [red]([/red][black][b]my[/b][/black] [blue]$line[/blue] = <FILE>[red])[/red] [red]{[/red]
	[black][b]chomp[/b][/black][red]([/red][black][b]my[/b][/black] [blue]@fields[/blue] = [url=http://perldoc.perl.org/functions/split.html][black][b]split[/b][/black][/url] [red]'[/red][purple],[/purple][red]'[/red], [blue]$line[/blue][red])[/red][red];[/red]
	[olive][b]if[/b][/olive] [red]([/red][blue]$emails[/blue][red]{[/red][blue]$fields[/blue][red][[/red][fuchsia]8[/fuchsia][red]][/red][red]}[/red][red])[/red] [red]{[/red]
		[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] OUT [url=http://perldoc.perl.org/functions/join.html][black][b]join[/b][/black][/url][red]([/red][red]'[/red][purple],[/purple][red]'[/red], [blue]@fields[/blue][red][[/red][fuchsia]0[/fuchsia],[fuchsia]1[/fuchsia],[fuchsia]7[/fuchsia],[fuchsia]8[/fuchsia][red]][/red][red])[/red], [red]"[/red][purple][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
	[red]}[/red]
[red]}[/red]
If you're not going to do any processing of the lines from the big file other than to print them out there's no need to store them in an array.

One other thing, if there's any possibility that the field delimiter (in this case a comma) can show up in the data in your big file you might want to consider using a module like Text::CSV_XS to do the splitting for you.

(And thanks to KevinADC for the code highlighting!)
 
Hello,

I appreciate the response, but your code doesn't even do what my above code is trying to do. We need to compare the value stored in $fields[8]} with each email in the list of emails. It needs a double loop, like I was trying to do. Inner outer loop. The outer loop being the list of validated email addresses. As you go through each one of these, you have to read in a line from the big file and go through each row to locate the email that matches the current email from the list. Both files are sorted in alphabetical order and every email in the validated list came from the big list. Upon matching then you write out the stuff to the outfile.

My code starts to do this and it finds the first match, but it is stuck on the first match and never gets to the second match, and it is stuck in an endless loop.



Thanks,

Scot King
Get your page rank high
 
I'm still not entirely sure what you are trying to achieve. If you could provide example data, it would help.

Chris
 
Zip Code County Phone Website Email
...

When the file is done writing, it will contain each row from the large list with 9 columns that has an email column with a matching email address. Do you understand?


Thanks,

Scot King
Get your page rank high
 
So let me restate this problem how I'm understanding it:

List1 (emails.txt) is a verified-good subset of email addresses from List2. List2 is a list of all submitted user contact info.

You're trying to verify if an email address from a line in List2 is valid by comparing it with the known good email addresses in List1. And, if the email is valid, print the record from List2. Have I got that pretty much right?

If that is what you're trying to do, did you even try the code I posted? This kind of problem doesn't really require nested loops, the hash will make things easier on you.

Although not exactly the same as your problem, the discussion associated with this recipe from the perl cookbook is relevant to what you're doing:
 
Hi! I've got it working now. It does what I need it to do. here is the solution I got:

#!/usr/bin/perl

my $path="C:/1millrealtors/";
my $outfile="fileout.txt";
##########################################################
# open output file
open(OUT,">$path$outfile") || die ("Can't open file!");

# open file of verified emails
print "Input Verified Email list (i.e. CA16331.txt : ";
my $vemailfile=<stdin>;
$vemailfile=substr($vemailfile, 0,length($vemailfile)-1);
open(EMAIL,"$path$vemailfile") || die ("Can't open file!");

# open complete file
open(FILE,"/1millrealtors/emailfileout.csv") || die ("Can't open file!");
print "Content-type: text/html\n\n";

my $row=<EMAIL>;
chomp($row);
do {
my $line= <FILE>;
print $line;
chomp(my @field = split ',', $line);

if ($field[9] eq $row) {
print $field[0] . "," . $field[8] . "," . $field[9] . "\n" ;
print OUT $field[0] . "," . $field[8] . "," . $field[9] . "\n" ;
$row=<EMAIL>;
chomp($row);
}
} while ($field[9] ne $row) ;
close FILE;
close EMAIL;

Thanks,

Scot King
Get your page rank high
 
Even though the inner loop scans an in-memory list, it's still hugely inefficient compared to using a hash, as rharsh has already noted. I've changed it to use Text::CSV_XS to parse the CSV, which is a lot safer than your method. And I've got rid of the hard coded filenames to make it more flexible (not to mention quite a bit shorter).
Perl:
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV_XS;

my $verified = shift;
my %verifiedEmail;

open(VERIFIED, $verified) or die "Can't open verified email file $verified: $!";

while (<VERIFIED>) {
   chomp;
   $verifiedEmail{$_}++;
}

close(VERIFIED);

my $csv = new Text::CSV_XS;

while (<>) {
   $csv->parse($_);
   my @fields = $csv->fields();
   print join(',', ($fields[0], $fields[8], $fields[9])), "\n" if exists $verifiedEmail{$fields[9]};
}

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top