use strict; use warnings; use DBI; use Text::CSV_XS; use IO::File; my ($file1,$file2) = @ARGV[0..1]; # two first args are files to compare # create a session filename my $dbfile = \"Session"; { my $sid = "$dbfile"; #stringify ref $sid = $1 if m/^SCALAR\((.*?)\)/; #remove all but address $dbfile = "$sid.db"; } #prepare to read files my $csv = Text::CSV_XS->new(); my $io1 = IO::File->new($file1,'<') or die ("Can't open $file1 for read: $!"); my $io2 = IO::File->new($file2,'<') or die ("Can't open $file2 for read: $!"); my $out = IO::File->new("$dbfile.csv",'>') or die ("Can't write outfile: $!"); #init DB connection my $dbh = DBI->connect("dbi:SQLite2:dbname=$dbfile",'','',{RaiseError =>1}); # Now, read file1 into the DB. print STDERR "loading $file1 into database...\n"; #-> first line of CSV is header row my $head1 = $csv->getline($io1); # create table $dbh->do( 'CREATE TABLE file ('.join(' TEXT,',@$head1).' TEXT)' ); # load db { my $sth = $dbh->prepare( 'INSERT INTO file ('.join(',',@$head1). ') VALUES ('.join(',',map {'?'} @$head1).')' ); until ($io1->eof) { my $row = $csv->getline($io1); $sth->execute(@$row); } } # ok, now compare file2 with what's in the DB. print STDERR "Beginning comparison.\n"; # assuming same header row $csv->getline($io2); { my $sth = $dbh->prepare( 'SELECT '.join(',',@$head1).' FROM file WHERE '. join(' AND ',map { "$_ = ?" } @$head1). ' LIMIT 1' ); until ($io2->eof) { my $row = $csv->getline($io2); $sth->execute(@$row); my $result = $sth->fetchrow_arrayref; if (defined $result && @$result) { print STDERR '+'; $csv->print($out,$row); #save matches to CSV } else { print STDERR '-'; } } print STDERR "\ndone.\n"; } print STDERR "Results saved to $dbfile.csv"; # clean up. $dbh->disconnect(); unlink($dbfile);