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

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

Hello Perl Monks I am new to Perl and I am having a problem trying to compare two text files and from what I have read a hash should be able to solve my problem. I am working on a unix system and what I am trying to do is to compare what is currently mounted against a master configuration file of what should be mounted. I have created a file with what is currently mounted and this is looks like this. There are alot more entries than this but this is just a small sample (mount point and volume where mounted):

/home filer1232:/vol/home1 /mystuff filer1233:/vol/project /data filer1234:/vol/example_data /tools filer1235:/vol/my_tools
The master configurtation file I have which lists everything that should be mounted looks like this (there are alot more entries than this but this is just a small sample):
/home filer1232:/vol/home1 /mystuff filer1233:/vol/project /data filer1234:/vol/example_data /software filer1255:/vol/my_software /tools filer1235:/vol/my_tools /docs filer146:/vol/my_documents
What I am having trouble with is creating a hash. I can read both of these two files into two separate arrays but what I am struggling with is how to output the difference. For example I have array1 which contains master configuration of everything that should should be mounted (mount point and volume mounted on) and I want to compare this with array2 which has whats currently mounted (mount point and volume mounted on). I basically what to be able to find whats not currently mounted as per the master configuration file. Please can you help me I have been struggling with this for ages

Replies are listed 'Best First'.
Re: How to find the difference between two text files using a hash array
by LanX (Saint) on Jan 20, 2013 at 21:29 UTC
    There is a short way to do it, but it's a bit complicated for beginners to understand:
    use strict; use warnings; use Data::Dumper; my @config = ( '/home filer1232:/vol/home1', '/mystuff filer1233:/vol/project', '/data filer1234:/vol/example_data', '/software filer1255:/vol/my_software', '/tools filer1235:/vol/my_tools', '/docs filer146:/vol/my_documents', ); my @mounted = ( '/home filer1232:/vol/home1', '/mystuff filer1233:/vol/project', '/data filer1234:/vol/example_data', '/tools filer1235:/vol/my_tools', ); my %diff; @diff{@config}=(); delete @diff{@mounted}; print Dumper [keys %diff];
    output
    $VAR1 = [ '/docs filer146:/vol/my_documents', '/software filer1255:/vol/my_software' ];

    See also

  • Using hashes for set operations...

  • How do I compute the difference of two arrays? How do I compute the intersection of two arrays?.

    (EDIT:repaired FAQ link)

    Cheers Rolf

      Thanks alot Rolf. I tried your suggestion and this is working perfectly :-)
Re: How to find the difference between two text files using a hash array
by roboticus (Chancellor) on Jan 20, 2013 at 21:41 UTC

    NewLondonPerl1:

    This is a pretty common question, so if you look at the perlfaq docs (specifically see "How can I remove duplicate elements from a list or array" and the next few articles in perlfaq4), it'll show you what you need to know.

    Since a hash lets you access a value given a key, you typically do it by first loading your hash with the values you want. As you read the second file, you can check whether the value is in the hash or not.

    $ cat t.pl #!/usr/bin/perl use strict; use warnings; my %H = (a=>1, d=>2); while (<DATA>) { s/\s+$//; if (exists $H{$_}) { print "$_ exists in hash\n"; } else { print "$_ missing from hash\n"; } } __DATA__ a b c d

    Running this script should give you:

    $ perl t.pl a exists in hash b missing from hash c missing from hash d exists in hash

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: How to find the difference between two text files using a hash array
by Kenosis (Priest) on Jan 20, 2013 at 21:33 UTC

    Consider using List::Compare to compare the two arrays. Below is an example of its use. The results show items that appear only in the left list contained by @array1:

    use strict; use warnings; use List::Compare; my @array1 = split /\n/, <<END1; /home filer1232:/vol/home1 /mystuff filer1233:/vol/project /data filer1234:/vol/example_data /software filer1255:/vol/my_software /tools filer1235:/vol/my_tools /docs filer146:/vol/my_documents END1 my @array2 = split /\n/, <<END2; /home filer1232:/vol/home1 /mystuff filer1233:/vol/project /data filer1234:/vol/example_data /tools filer1235:/vol/my_tools END2 my $lc = List::Compare->new( \@array1, \@array2 ); my @Lonly = $lc->get_unique; print "$_\n" for @Lonly;

    Output:

    /docs filer146:/vol/my_documents /software filer1255:/vol/my_software
      Thanks alot everyone for your help. I will try this out now
      Ok I have tried using List::Compare and unfortunately we dont have this perl module. I am going to try out these other suggestions now

        Below generates the same results w/o using the module:

        use strict; use warnings; my @array1 = split /\n/, <<END1; /home filer1232:/vol/home1 /mystuff filer1233:/vol/project /data filer1234:/vol/example_data /software filer1255:/vol/my_software /tools filer1235:/vol/my_tools /docs filer146:/vol/my_documents END1 my @array2 = split /\n/, <<END2; /home filer1232:/vol/home1 /mystuff filer1233:/vol/project /data filer1234:/vol/example_data /tools filer1235:/vol/my_tools END2 my %currMounted = map { $_ => 1 } @array2; print "$_\n" for grep !$currMounted{$_}, @array1;
Re: How to find the difference between two text files using a hash array
by NetWallah (Canon) on Jan 20, 2013 at 21:32 UTC
    Please check perlfaq4 for How-do-I-compute-the-difference-of-two-arrays?.

                 Most people believe that if it ain't broke, don't fix it.
            Engineers believe that if it ain't broke, it doesn't have enough features yet.