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

Dear All,

Please find the script below which although doesnt have immediate errors..is not what I was hoping it would acheive!

#perl -w print("Importing two data files \n"); # Lets open up file A which reads data from names_ticker to FILE_A open(FILE_A, "< Names_Ticker.txt") or die "Couldn't open Names_Ticker for reading: $!\n"; @fileA=<FILE_A>; close(FILE_A); print "@fileA \n"; # Lets open up file B which reads data from names_offer to FILE_B open(FILE_B, "< Names_Offer.txt") or die "Couldn't open Names_Offer for reading: $!\n"; @fileB=<FILE_B>; close(FILE_B); print "@fileB \n"; #Print the lists generated with commas... sort the format out! #sub commify_series { # my $sepchar = grep(/,/ => @_) ? ";" : ","; # (@_ == 0) ? '' : # (@_ == 1) ? $_[0] : # (@_ == 2) ? join(" and ", @_) : # join("$sepchar ", @_[0..($#_-1)], "and $_[-1]"); # } # #foreach $aref(@fileB) { # print "This lists contains: " . commify_series(@aref) . ".\n" +; # #} print("Comparing company names between two files\n"); # Essentially we want to find elements that are in one array but not a +nother, # that is find elements in @fileA that arent in @fileB. # Solution? build hash keys of @fileB to use as a lookup table. Then c +heck each # element in @fileA to see if it is in @fileB %seen = () ; # lookup table to test memebership of @fileB @aonly = () ; # answer # build lookup table foreach $item (@fileB) { $seen{$item} = 1} # find only elements in @fileA and not in @fileB foreach $item (@fileA) { unless ($seen{$item}) { # its not in %seen, so add to @aonly push(@aonly, $item); } } print "@aonly \n"; print("Saving matched company records as new file\n");

Ideally, as suggested from previous email - I am merging two records @fileA and @fileB into a single new file which is given as @aonly.

Problems I face:
  1. the contents of @fileA and @fileB - I would like to convert everything into lower capitals
  2. can I add a search condition to this script which would search (a) the first 4 letters of each string in the arrays (either from the start or end of line? )

Your advice will be appreciated.

regards

Edited by Chady -- cleaned up formatting

Replies are listed 'Best First'.
Re: Fuzzy Matching
by !1 (Hermit) on Dec 30, 2003 at 09:55 UTC

    1. map and lc are your friends.

    2. I don't know what exactly you want but I can tell you substr will definitely help as might split.

    As a side note: you may wish to use code tags (<code></code>) next time you wish to post code.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Fuzzy Matching
by Art_XIV (Hermit) on Dec 30, 2003 at 14:10 UTC

    I'm not sure what the question really is, but maybe this will give you some ideas:

    #Don't forget to use these! use warnings; use strict; my %in_file_b; my @aonly; my ($file_a, $file_b) = ('Names_Ticker.txt', 'Names_Offer.txt'); print("Importing two data files \n"); #Look at FILE_B first since we will be eliminating elements #from FILE_A based upon its contents open(FILE_B, "<$file_b") or die "Couldn't open $file_b for reading: $!\n"; while (<FILE_B>) { chomp; #the key will be the first four chars of the line, lowercase my $entry = lc( substr $_, 0, 4); #substr $_, -4 would get last fo +ur $in_file_b{$entry} = 1; } close FILE_B; open(FILE_A, "<$file_a") or die "Couldn't open $file_a for reading: $!\n"; while (<FILE_A>) { chomp; my $entry = lc( substr $_, 0, 4); #add the entire line if the value of $entry isn't in %in_file_b push @aonly, $_ unless exists $in_file_b{$entry}; } close FILE_A; print "@aonly\n"; 1;

    Processing it like this avoids slurping one of the files into memory.

    Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"