http://www.perlmonks.org?node_id=820610

kirkbrown has asked for the wisdom of the Perl Monks concerning the following question:

I have data that I want to compare to a temp and master file. Then submit a report showing what data is different from the master file and what data is not in the master file. The data looks similar to this:

crrobert1 S3H24 999-4574 Main Bldg
kcbens4 T3222 410-6677 Physical Plant

I want to:
1. Match each line based on the first group of 5-7 characters
2. Compare the temp file lines master file line to see if each line is present and matches.
3. Create report listing lines (Both master and temp file) that are different or not present

Replies are listed 'Best First'.
Re: Search, Match, Compare, and Report
by BrowserUk (Patriarch) on Jan 31, 2010 at 20:18 UTC

    Load the master file into a hash; read the temp file line-by-line and check for existance; compile report.

Re: Search, Match, Compare, and Report
by ikegami (Patriarch) on Jan 31, 2010 at 22:18 UTC
    sub load { my ($qfn) = @_; open(my $fh, '<', $qfn) or die("Can't open file \"$qfn\": $!\n"); my %data; local *_; while (<$fh>) { my ($id) = /^(\S+)/ or next; die("Duplicate key $id\n") if exists($data{$id}); $data{$id} = $_; } return \%data; } my $master = eval { load(...) } or die("Can't load master db: $@"); my $new = eval { load(...) } or die("Can't load new db: $@"); my %ids; for my $id (keys(%$master), keys(%$new)) { next if $ids{$id}++; if (!exists($new->{$id})) { print("-$master->{$id}"); } elsif (!exists($master->{$id})) { print("+$new->{$id}"); } elsif ($master->{$id} ne $new->{$id}) { print("-$master->{$id}"); print("+$new->{$id}"); } else { print("=$master->{$id}"); } }

    Update: Added missing parens and fixed var name as per reply.

      Looks interesting, what local *_; actually does in this code?

      BTW, There are few missing brackets & $keys{$id}++ meant to be $ids{$id}++ in your code right below the for loop.

        while (<...>)
        is short for
        while (defined($_ = <...>))

        local *_; prevents the clobbering of the parent's $_. my $_; would also do the trick in Perl 5.10+

      Thank you very much Monks! Another question, If I have two .txt files, how do I pass the files into the program? I'm new to Perl and programming.
        Command line arguments are provided via @ARGV
Re: Search, Match, Compare, and Report
by linuxer (Curate) on Jan 31, 2010 at 18:58 UTC

    Hi and welcome.

    So you have a list of what you want. But you didn't specify what you expect from the monks exactly.

    What's the code you have so far? Where do you have problems?

Re: Search, Match, Compare, and Report
by biohisham (Priest) on Jan 31, 2010 at 21:53 UTC
    2. Compare the temp file lines master file line to see if each line is present and matches.

    See Printing Line Numbers in output file for a similar discussion...


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: Search, Match, Compare, and Report
by Anonymous Monk on Jan 31, 2010 at 19:19 UTC
    On a very basic level File::Compare does a line by line check on two files, however, it stops as soon as a difference is detected...


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.