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

Any easy way to do this in Perl? I need a function which take __arbitrary__ unix paths and compares them

# unix echo $path1 | tr '/' '\n/ > 1.txt echo $path2 | tr '/' '\n' > 2.txt diff 1.txt 2.txt /a/b/c/different/x/y/z <--> /a/b/c/somethingelse/x/y/z ?

Replies are listed 'Best First'.
Re: Comparing Elements of Two Arrays
by jeroenes (Priest) on May 30, 2001 at 15:18 UTC
    Use split and grep to compare.

    Untested example:

    sub compare_paths{ my @path1 = split /\//, +shift; split /\//, +shift; grep $_ ne +shift, @path1; }
    Returns a list with elements from path1 that do not match.

    Hope this helps,

    Jeroen
    "We are not alone"(FZ)

    Update: This modification is better, now it returns a hash:

    sub compare_paths{ my @path1 = split /\//, +shift; split /\//, +shift; grep { defined $_} map {my $n = +shift; $_ ne $n ? ($_,$n) : undef} +@path1; }
    (and it is tested now. It returns a true in scalar context; the keys of the hash give you the number of mismatches in scalar context)
Re: Comparing Elements of Two Arrays
by merlyn (Sage) on May 30, 2001 at 16:52 UTC
Re: Comparing Elements of Two Arrays
by bikeNomad (Priest) on May 30, 2001 at 17:56 UTC
    To expand on merlyn's excellent <g> suggestion, the following is an example of using Algorithm::Diff for comparing paths. Of course, I'm not sure that this is what you mean by "compare", but since you show the use of diff, perhaps it is:
    #!/usr/bin/perl -w use strict; use Algorithm::Diff; die "usage: $0 path1 path2\n" unless $#ARGV == 1; my @path1 = split('/', $ARGV[0]); my @path2 = split('/', $ARGV[1]); sub match { print "same:\t$path1[$_[0]]\t$path2[$_[1]]\n"; } sub discA { print "omitA:\t$path1[$_[0]]\n"; } sub discB { print "omitB:\t\t$path2[$_[1]]\n"; } Algorithm::Diff::traverse_sequences( \@path1, \@path2, { MATCH => \&match, DISCARD_A => \&discA, DISCARD_B => \&discB });
Re: Comparing Elements of Two Arrays
by chipmunk (Parson) on May 30, 2001 at 20:20 UTC
    There's another kind of comparison that can be done on two paths, which is to see if they refer to the same file (or directory). This is especially useful when you have relative paths or paths that include symlinks, and you want to know whether they resolve to the same absolute path.
    sub compare_paths { my($dev1, $inode1) = stat $_[0]; my($dev2, $inode2) = stat $_[1]; return unless defined $dev1 and defined $dev2; return $dev1 == $dev2 && $inode1 == $inode2; }
    This returns true if the paths point to the same file, false (defined) if they don't, and undef if either stat fails (probably because the file doesn't exist).