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

I am comparing all the lines in a file, the first compare always works but after that they all go false.. I cant think of what to do for the life of me. please help :+)

open (saved_system, "saved_system.txt"); open (current_system, "current_system.txt"); open (deleted_archeive, ">>deleted.txt"); while ($saved_system = <saved_system>) { chomp; while ($current_system = <current_system>){ chomp; if ($saved_system eq $current_system) { print " Files are equal\n" +;} elsif ($saved_system ne $current_system) {print " Files are not eq +ual\n";} } }

Replies are listed 'Best First'.
Re: comparing lines in two files
by ikegami (Patriarch) on Jan 01, 2010 at 11:09 UTC

    As per our conversation in the CB,

    use strict; use warnings; open(my $sav_fh, '<', 'saved_system.txt' ) or die; open(my $cur_fh, '<', 'current_system.txt') or die; my @sav_files = sort <$sav_fh>; my @cur_files = sort <$cur_fh>; my @rem_files; my @new_files; while (@sav_files && @cur_files) { if ($sav_files[0] lt $cur_file[0]) { push @rem_files, shift(@sav_files); } elsif ($sav_files[0] gt $cur_file[0]) { push @new_files, shift(@cur_files); } else { shift @sav_files; shift @cur_files; } } push @rem_files, @sav_files; push @new_files, @cur_files; open(my $rem_fh, '>', 'removed.txt') or die; print $rem_fh @rem_files;
Re: comparing lines in two files
by bobr (Monk) on Jan 01, 2010 at 07:58 UTC
    Hi,

    If you want just know there was a change, go with File::Compare mentioned above.

    I think you probably need to know what files were added and removed, in other word difference between your file list. You can try following approach:

    First make sure your lists in files are sorted. Then use Text::Diff module like this:

    use Text::Diff; my $diff = diff "saved_system.txt", "current_system.txt", { STYLE => " +OldStyle" }; my (@added,@removed); for(split /\n/,$diff) { next if /^\d/; # skip line numbers push @added,$1 if /^> (.*)$/; push @removed,$1 if /^< (.*)$/; } print "Added files:\n"; for my $file (@added) { print $file,"\n"; } print "\nRemoved files:\n"; for my $file (@removed) { print $file,"\n"; }

    It prints output to console, but it is easy to change for printing into file.

    -- hope this helps, Roman

      It seems to me that will fail if saved_system.txt and current_system.txt are ordered differently.
        Agree completely, thats why I pointed that lists have to be sorted. Since this seems to be followup to storing all file info, I assumed that no problem make lists sorted on its creation.

        On any case, your solution below seems to be more elegant and independent on libraries.

        -- Roman

Re: comparing lines in two files
by biohisham (Priest) on Jan 01, 2010 at 11:15 UTC
    Just to be on the safe side, I'd advice you to habitually use the strictures ,this is like the ABS system in a car and can really stabilize you from slipping into errors or typos:
    use strict; use warnings;

    Another advice is to use the three argument form of open and show the open modes your files are accessed under (input, output, appending, piping...),

    open (FH, '<', "saved_system.txt");

    A third advice with open is to provide for explanation/clues of errors that could ensue, like if the file couldn't be opened, didn't exist, didn't have access attributes and more importantly if system-errors where involved, these clues can be indicated from $!..
    open(FH, '<', 'saved_system.txt')or die("Couldn't open file, $!");
    to read the perlvar documentation for $! from the terminal prompt of your machine, "perldoc perlvar $!"

    Update:ikegami posted a wholesome example while I was writing these ideas :)...


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.
Re: comparing lines in two files
by Anonymous Monk on Jan 01, 2010 at 07:04 UTC