DaedalusUsedPerl
DaedalusUsedPerl

Reputation: 772

Linux: How do I compare all files in a directory against each other?

For my homework, I have to check if two files in a directory have the same contents and if so, replace one with a hardlink to the other. My script looks like:

    cd $1 # $1 is the directory this script executes in
    FILES=`find . -type f`
    for line1 in $FILES
    do
       for line2 in $FILES
       do
         (check the two files with cmp)
       done
    done

My problem is that I can not figure out the conditional expression to make sure that the two files are not the same: If the directory has files a,b,c, and d it should not return true for checking a against a. How do I do this?

Edit: So I've got this:

cmp $line1 $line2 > /dev/null
if [ $? -eq 0 -a "$line1" != "$line2" ]

But it counts the files twice: It checks a and b, and then b and a. for some reason, using < with strings does not work.

Edit: I think I figured it out, the solution is to use a \ before the <

Upvotes: 0

Views: 224

Answers (2)

jlliagre
jlliagre

Reputation: 30813

Here is an optimized way to do it that also properly handle files with embedded spaces or similar:

find . -type f -exec sh -c '
compare() {
  first=$1
  shift
  for i do
    cmp -s "$first" "$i" || printf " %s and %s differ\n" "$first" "$i"
  done
}
while [ $# -gt 1 ]; do
  compare "$@"
  shift
done ' sh {} +

Upvotes: 0

user149341
user149341

Reputation:

Using test, or its alias [:

if [ "$line1" < "$line2" ]
then
    check the files
fi

Note that I'm using < here instead of != (which would otherwise work) so that, once you've compared a with b, you won't later compare b with a.

Upvotes: 1

Related Questions