Gossamer Forum
Home : General : Perl Programming :

Comparing data from 2 files

Quote Reply
Comparing data from 2 files
Hi,
I have two flat text files that I want to use to update data. Here is my setup:

File 1:
drehan|Rucchin, Steve|C|10|2|3|4|0
drehan|Leclair, John|C|9|10|3|12|0
drehan|Fedorov, Sergei|C|10|2|7|0|0

File 2:
Selanne, Teemu|75|47|60|107|30
Kariya, Paul|82|39|62|101|40
Rucchin, Steve|69|23|39|62|22

File one is the original database while File 2 is an update file. I need to parse File 1, look for the player name from File 1 in File 2 and update fields 3,4,5 & 6.

After running, my File one should change from what it is above to:

File 1a:
drehan|Rucchin, Steve|C|75|47|33|107|30
drehan|Leclair, John|C|9|10|3|12|0
drehan|Fedorov, Sergei|C|10|2|7|0|0

Any ideas? Thanks.
Quote Reply
Re: Comparing data from 2 files In reply to
Sigh!?

[This message has been edited by Chris071371 (edited November 30, 1999).]
Quote Reply
Re: Comparing data from 2 files In reply to
Code:
open(OF, "file1") | | die "$!\n";
@file1 = <OF>;
close(OF);
open(UF, "file2") &#0124; &#0124; die "$!\n";
@file2 = <UF>;
close(UF);
foreach $line (@file1) {
chomp($line);
($f1,$f2,$f3) = split(/\|/, $line);
chomp(($to_update) = grep /^$f2\|/, @file2);
@update = split(/\|/, $to_update);
splice(@update, 0, 1);
$update[0] ne "" ? push(@new_file, (join '|', $f1, $f2, $f3, @update)) : push(@new_file, $line);
}
open(NF, ">file1") &#0124; &#0124; die "$!\n";
print NF "$_\n" foreach (@new_file);
close(NF);

TMTOWTDI
I presume that you meant to put Steve Rucchin's stats and not Teemu Selanne's on Steve Rucchin.
-- Gordon --


------------------
$blah='82:84:70:77';
print chr($_) foreach (split/:/,$blah);

Quote Reply
Re: Comparing data from 2 files In reply to
Hmm..I'll try this out. Btw, this is what I have so far and I suspect that there are some problems with scoping along with other bugs aswell. This code does not work:

#!/usr/local/bin/perl

use English;
use Fcntl;
use Symbol;

my $db_original_path = "default.db";
my $db_updates_path = "stat.out";

sysopen(my $db_original_f = gensym, $db_original_path, O_RDONLY)&#0124; &#0124;
die "$0: open of $db_original_path failed: $!\n";
sysopen(my $db_updates_f = gensym, $db_updates_path, O_RDONLY)&#0124; &#0124;
die "$0: open of $db_updates_path failed: $!\n";

my %db_original;
my @db_original;
my $updates_applied = 0;

local $SUBSCRIPT_SEPARATOR = "|"; # Also known as $;
local $_;

# Scan the original db in.
while (<$db_original_f> ) {

my($gm, $player, $position, $goals, $assists, $pim, $points) = split(/\|/, $_);
$db_original{$player} = [$goals, $assists, $pim];
push(@db_original, [$player]);
}
close($db_original_f);

# Scan the updates db, performing changes on the fly.
while (<$db_updates_f> ) {

my($player, $goals, $assists, $poinsts, $pim) =
split(/\|/, $_);

# If the original db has an entry that matches this one,
# replace the non-instance fields with the updates.
if (exists $db_original{$player}) {
$db_original{$player} = [$goals, $assists, $pim];
$updates_applied++;
}
}
close($db_updates_f);

# Write out the new db.
sysopen(my $db_new_f = gensym, "$db_original_path.new",
O_WRONLY | O_CREAT | O_TRUNC) &#0124; &#0124;
die "$0: open of $db_original_path.new for writing failed: $!\n";
{
local $OUTPUT_FIELD_SEPARATOR = "|"; # Also known as $,
local $OUTPUT_RECORD_SEPARATOR = "\n"; # Also known as $\

for (@db_original) {
my($player) = @$_;
my($player) = @{ $db_original{$player} };
print $db_new_f $gm, $player, $position, $goals, $assists, $pim, $points;
}
}
close($db_new_f) &#0124; &#0124;
die "$0: fsync of $db_original_path.new failed: $!\n";

# Success!
print "$updates_applied updates were applied.\n";
exit 0;
Quote Reply
Re: Comparing data from 2 files In reply to
Or you could use Chris's code which is longer and limited Smile

-- Gordon --


------------------
$blah='82:84:70:77';
print chr($_) foreach (split/:/,$blah);


[This message has been edited by GClemmons (edited November 30, 1999).]
Quote Reply
Re: Comparing data from 2 files In reply to
I am extrememly sorry guys....I made a mistake in the output file. Steve Rucchin's stats should be updated with his own, ideally when used with the complete update file, Leclair and Fedorov would have their stats updated as well.

It should read:
File 1a:
drehan|Rucchin, Steve|C|69|23|39|62|22
drehan|Leclair, John|C|9|10|3|12|0
drehan|Fedorov, Sergei|C|10|2|7|0|0
Quote Reply
Re: Comparing data from 2 files In reply to
No worries Smile it will work either way as long as the names are the same in both files Smile
-- Gordon --


------------------
$blah='82:84:70:77';
print chr($_) foreach (split/:/,$blah);

Quote Reply
Re: Comparing data from 2 files In reply to
Hum de dum

[This message has been edited by Chris071371 (edited November 30, 1999).]
Quote Reply
Re: Comparing data from 2 files In reply to
You admit yourself that your code requires him to have the same fields in his update as in his database.
Oh, and... damn:
Code:
$finishline = "$line[0]\|$line[1]\|$line[2]\|$update[1]\|$update[2]\|$update[3]\|$update[4]\|$update[5]\n";

Nuff said.
-- Gordon --


------------------
$blah='82:84:70:77';
print chr($_) foreach (split/:/,$blah);

Quote Reply
Re: Comparing data from 2 files In reply to
Flame War (weeeeeeeeeeeeeee haaaawww!) Time to referee:

Quote:
Your post wasn't even here when I posted mine.

GClemmons posted 11-30-99 11:11 AM PST
Chris071371 posted 11-30-99 12:48 PM PST

(uh oh!)

Quote:
I was stating to DIV, that there are more fields, count'em, 8, in file 1 than file 2(6).

From the original specs:

Quote:
File one is the original database while File 2 is an update file. I need to parse File 1, look for the player name from File 1 in File 2 and update fields 3,4,5 & 6.

Anything past 6 fields is irrelevant for the requested function since it's not doing a complete swap. Not to mention, they're just doing a substitution of some fields in the file with more fields.

Quote:
There is nothing LIMITED about my code

Except:

Quote:
This assumes that every person in file 1 has a record in file 2

If we make the assumption that all players won't necessarily update each time, then it is a severe limitation. The functionality to take this into account needs to be added in, unless the specs were to specifically state that it's all players all the time.

As Gordon said in his post, TMTOWTDI, which means There's More Than One Way To Do It.

Everyone has there own method and way of accomplishing tasks. If it works, that's great. Some solutions are more elegant than others, but whatever works for a given situation. The trick is to always look at what other people do, and learn from them. I learn new/better things with Perl everyday.

*crash* (sorry, my soapbox gave out under me)

Now everyone quit fighting or I'm sending you to your homepages without any supper.



--mark

------------------
Due to repeated requests for support via ICQ, I am once again offering support online.

The ONLY number I will accept requests on is #53788453. Messages sent to my other numbers will not pass through to me, as I have security settings set to ignore messages from users not on that list.

I don't know how often I will be active on this number, as it is for only when I am free to offer assistance.

Could this signature be any longer? :)
Quote Reply
Re: Comparing data from 2 files In reply to
Here you go DIV, since Gordon's code serves up a nice 500 error. Maybe he should look at:
Code:
print NF "$_\n" foreach (@new_file);

Gordon's code will work if this line is written as:
Code:
foreach (@newfile) {
print NF "$_\n";
}

This will keep the ones where no match is found, as I misunderstood your initial post. I admit my code is a little long, I didn't have a whole lot of time to think about it. It does work though. Chill out Gordon, this is only a script the guy will probably use only once.:

Code:
#!/usr/bin/perl
open (TEC, "/home/chris/www/filea.txt") &#0124; &#0124; die "Can't open file";
@filea = (<TEC> );
close (TEC);
open (TED, "/home/chris/www/fileb.txt") &#0124; &#0124; die "Can't open file";
@fileb = (<TED> );
close (TED);
MAIN: foreach (0 .. $#filea) {
chomp($filea[$_]);
@line = split(/\|/,$filea[$_]);
$count=0;
LOOP: foreach $row (@fileb) {
chomp($row);
@update = split(/\|/,$row);

if ($line[1] eq "$update[0]") {
$finishline = "$line[0]\|$line[1]\|$line[2]\|$update[1]\|$update[2]\|$update[3]\|$update[4]\|$update[5]\n";
push(@finish,$finishline);
next MAIN;
}
elsif (($count == ($#fileb - 1)) && ($line[1] ne "$update[0]")) {
$finishline = "$line[0]\|$line[1]\|$line[2]\|$line[3]\|$line[4]\|$line[5]\|$line[6]\|$line[7]\n";
push(@finish,$finishline);
next MAIN;
}

$count++;
}
}

open (TEC, ">/home/chris/www/filea.txt") &#0124; &#0124; die "Can't open file";
print TEC @finish;
close (TEC);
print "Content-type: text/html\n\n";
print "@finish";
exit;

------------------
WFMY-TV Webmaster
Quote Reply
Re: Comparing data from 2 files In reply to
OK Mark, we can all tell time, but when I came to this post, there were no replies. Perhaps Gordon submitted his post while I was writing mine. I left to take lunch in the middle of writing it. I didn't mean for him to get his panties in a wad. I was just trying to help someone. This is where I got help when I first started, so I try to give back every once in a while. I guess I'll stay out of Master Gordon's way. He's good with PERL, but a SMARTASS!

------------------
WFMY-TV Webmaster
Quote Reply
Re: Comparing data from 2 files In reply to
Firstly, a 500 error? This isn't a web application and that is why it gives a 500 error. I've tested my code on both Win32 and Unix platforms and it works fine. If you want to keep from getting
Code:
print NF "$_\n" foreach (@new_file);
works perfectly fine.
-- Gordon --


------------------
$blah='82:84:70:77';
print chr($_) foreach (split/:/,$blah);

Quote Reply
Re: Comparing data from 2 files In reply to
Ah, the ole Time-overlapper Delio (tm). Yup. It happens. No harm, no foul.

Don't mind me, I just like jumping in to arguments and being a pain in the ass.... Smile

Chris.. Nothing wrong with trying to give back. I don't think Gordon was trying to be a smartass when he said your code was longer and limited. There was a smiley on the end of his post.

Let's have everyone cool down and stop trying to out-do each other.

Div... quit posting! Look what ya started! Smile (I'm kidding Div, keep posting as often as you like!).



--Mark

------------------
Due to repeated requests for support via ICQ, I am once again offering support online.

The ONLY number I will accept requests on is #53788453. Messages sent to my other numbers will not pass through to me, as I have security settings set to ignore messages from users not on that list.

I don't know how often I will be active on this number, as it is for only when I am free to offer assistance.

Could this signature be any longer? :)
Quote Reply
Re: Comparing data from 2 files In reply to
Sorry about this whole mess, but you did take the first swing Gordon.

I was using your code as a web application and I did print the header. I still got a 500 error, until I changed that bit of code, then it worked fine. I don't doubt that yours works just fine.

I just want you to know that I misunderstood Div's original post, and that I didn't mean to get anything started, you just got a little jumpy.

Chris

------------------
WFMY-TV Webmaster
Quote Reply
Re: Comparing data from 2 files In reply to
I apoligise, it's been a long year Wink
Not enough sleep in the mean time...
I appreciate you offering your help on the forum.
-- Gordon --


------------------
$blah='82:84:70:77';
print chr($_) foreach (split/:/,$blah);

Quote Reply
Re: Comparing data from 2 files In reply to
Thanks for all your help guys!