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

Hello again Monks,

I was trying to create a script that will recursively check for differences between directories and print them.

In UNIX the most common is diff -r test1/ test2/.

Sample of output:

$ diff -r test1/ test2/ diff -r test1/common/common.txt test2/common/common.txt 1c1 < This is a common line --- > This is a common line. Only in test2/common: common.txt~ Only in test1/: different1 Only in test2/: different2

I came across with multiple questions and suggestions for example (Directory comparison) and (Recursive Directory Comparison Tools).

I also found the File::DirCompare module. Sample of script and output:

#!/usr/bin/perl use strict; use warnings; use Data::Dumper; sub check_dirs { die "Please provide 2 Directories!\n" unless ($#ARGV == 1); for (@_) { die "Input $_ is not a directory!\n" unless (-d $_) }; } check_dirs(@ARGV); use File::DirCompare; # Simple diff -r --brief replacement use File::Basename; File::DirCompare->compare($ARGV[0], $ARGV[1], sub { my ($a, $b) = @_; if (! $b) { printf "Only in %s: %s\n", dirname($a), basename($a); } elsif (! $a) { printf "Only in %s: %s\n", dirname($b), basename($b); } else { print "Files $a and $b differ\n"; } }); __END__ $ perl cmp.pl test1/ test2/ Files test1/common/common.txt and test2/common/common.txt differ Only in test2/common: common.txt~ Only in test1: different1 Only in test2: different2

But it does tell provides you with the information of which file(s) are different.So I decided to write my own script.

Script and output:

#!/usr/bin/perl use strict; use warnings; use Text::Diff; use File::Dircmp; use Data::Dumper; sub check_dirs { die "Please provide 2 Directories!\n" unless ($#ARGV == 1); for (@_) { die "Input $_ is not a directory!\n" unless (-d $_) }; } check_dirs(@ARGV); my @dircmp = dircmp($ARGV[0], $ARGV[1]); my @diff; foreach my $element (@dircmp) { if ($element =~ /^Files/) { my @tmp = split / /, $element; push @diff, diff $tmp[1] => $tmp[3]; } } print Dumper \@dircmp if (@dircmp); print @diff if (@diff); __END__ $ perl cmp.pl test1/ test2/ $VAR1 = [ 'Only in test1/: different1', 'Only in test2/: different2', 'Only in test2//common: common.txt~', 'Files test1//common/common.txt and test2//common/common.txt + differ' ]; --- test1//common/common.txt Wed Mar 8 11:41:08 2017 +++ test2//common/common.txt Wed Mar 8 11:44:35 2017 @@ -1 +1 @@ -This is a common line +This is a common line.

So my question is, have a missed something? Anyone knows any other module that I could use? I am not really happy the way my output is printed is there anything that I could do to make it better?

Thanks in advance for our time and effort reading and replying to my question.

Seeking for Perl wisdom...on the process of learning...not there...yet!

Replies are listed 'Best First'.
Re: Recursive Directory Comparison and Export Differences
by Corion (Patriarch) on Mar 08, 2017 at 12:54 UTC
Re: Recursive Directory Comparison and Export Differences
by shmem (Chancellor) on Mar 09, 2017 at 11:52 UTC
    So my question is, have a missed something?

    hmm... the output of your last script

    $VAR1 = [ 'Only in test1/: different1', 'Only in test2/: different2', 'Only in test2//common: common.txt~', 'Files test1//common/common.txt and test2//common/common.txt + differ' ]; --- test1//common/common.txt Wed Mar 8 11:41:08 2017 +++ test2//common/common.txt Wed Mar 8 11:44:35 2017 @@ -1 +1 @@ -This is a common line +This is a common line.

    is very similar to the output diff -ru produces:

    qwurx [shmem] ~/tmp/diff> diff -ur test1 test2 diff -ur test1/common/common.txt test2/common/common.txt --- test1/common/common.txt 2017-03-09 12:28:15.215474776 +0100 +++ test2/common/common.txt 2017-03-09 12:28:38.639837796 +0100 @@ -1 +1 @@ -This is a common line +This is a common line. Only in test2/common: common.txt~ Only in test1: different1 Only in test2: different2

    and it is trivial to filter that output to resemble that of your script.
    Perhaps you want to tell us what kind of output you are aiming for, and the purpose of it all?

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
Re: Recursive Directory Comparison and Export Differences
by Anonymous Monk on Mar 08, 2017 at 17:24 UTC
    don't reinvent wheels :)
    vagrant@localhost ~/foo $ mkdir bar
    vagrant@localhost ~/foo $ mkdir baz
    vagrant@localhost ~/foo $ echo test > bar/test
    vagrant@localhost ~/foo $ echo test2 > baz/test
    vagrant@localhost ~/foo $ echo foo > bar/foo
    vagrant@localhost ~/foo $ cd bar/
    vagrant@localhost ~/foo/bar $ git init
    Initialized empty Git repository in /home/vagrant/foo/bar/.git/
    vagrant@localhost ~/foo/bar $ git add .
    vagrant@localhost ~/foo/bar $ git commit -m'init'
    [master (root-commit) e360fb9] init
     2 files changed, 2 insertions(+)
     create mode 100644 foo
     create mode 100644 test
    vagrant@localhost ~/foo/bar $ mv .git/ ../baz/
    vagrant@localhost ~/foo/bar $ cd ../baz/
    vagrant@localhost ~/foo/baz $ git diff
    diff --git a/foo b/foo
    deleted file mode 100644
    index 257cc56..0000000
    --- a/foo
    +++ /dev/null
    @@ -1 +0,0 @@
    -foo
    diff --git a/test b/test
    index 9daeafb..180cf83 100644
    --- a/test
    +++ b/test
    @@ -1 +1 @@
    -test
    +test2