Skip to content

Instantly share code, notes, and snippets.

@RichardBronosky
Created March 12, 2010 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RichardBronosky/330096 to your computer and use it in GitHub Desktop.
Save RichardBronosky/330096 to your computer and use it in GitHub Desktop.
### Usage: compare_script.sh directory1 directory2
# This script can be used with 2 different functionalities, list_same or list_different
#functionality=list_same
functionality=list_different
# list_different will include files that exist only in the first directory. For
# that reason you will probably want to run it as:
# compare_script.sh dir1 dir2; compare_script.sh dir2 dir1
# gnu stat is very different that BSD stat, on a Mac you should install
# the gnu coreutils
stat=$(which gstat || which stat)
### Define the functions we'll be needing
same_size(){
if [[ -f $2 ]] && [[ $($stat --printf "%s" $1) == $( $stat --printf "%s" $2 ) ]]; then
return 0
else
return 1
fi
}
list_same(){
same_size $1 $2 && echo $1
}
list_different(){
same_size $1 $2 || echo $1
}
path_complement(){
# Usage: path_complement directory_1 directory_2 path_to_file_in_directory_1
# returns path_to_file_in_directory_1 path_to_file_in_directory_2
echo $3 $2/${3#${1}/}
}
# This is called by the find in main() below
callback(){
path=$($functionality $(path_complement $2 $3 $4))
if [[ -n "$path" ]]; then
# to return the whole path do:
echo $path
# to remove the dir1 portion from the path do:
#echo ${path#${2}/}
fi
}
main(){
# remove trailing slashes if they are present
dir1=${1%/}
dir2=${2%/}
# remove double slashes if they are present
dir1=${dir1/\/\//\/}
dir2=${dir2/\/\//\/}
find $dir1 -type f -exec $0 --callback $dir1 $dir2 {} \;
}
### Procedure
# The find command in main() cannot -exec functions, not files. For that reason
# we must give this script way to call itself as a callback.
if [[ $1 == "--callback" ]]; then
callback $*
else
main $*
fi
exit 0
### BEGIN UNIT TEST CODE ###
echo Creating client directories in /tmp/ for testing...
echo Removing /tmp/client*
rm -rf /tmp/client*
echo Create a dir structure to prove that it works on deep dirs
mkdir -p /tmp/client01/images/landscape/thumbnails
echo Create 10 files in each dir
for ((i=1; i <= 10; i++)); do find /tmp/client01 > /tmp/client01/images/landscape/file$(printf '%02d' $i).ext; done
for ((i=1; i <= 10; i++)); do find /tmp/client01 > /tmp/client01/images/landscape/asset$(printf '%02d' $i).ext; done
for ((i=1; i <= 10; i++)); do find /tmp/client01 > /tmp/client01/images/landscape/thumbnails/thumbnail$(printf '%02d' $i).ext; done
echo Copy the images dir over to a movies dir
cp -r /tmp/client01/images /tmp/client01/movies
echo Remove a file from each of the images dirs
find /tmp/client01/images -name '*5*' -exec rm {} \;
echo Remove a different file from each of the movies dirs
find /tmp/client01/movies -name '*6*' -exec rm {} \;
echo Put some alternate data in to create non-matching filesizes
for f in $(find /tmp/client01/images/ -name '*3*'); do ls -l > $f; done
for f in $(find /tmp/client01/movies/ -name '*4*'); do ls -l > $f; done
echo Create 10 /tmp/clients "(they'll all be the same, but you get the point)"
for ((i=2; i <= 10; i++)); do cp -r /tmp/client01 /tmp/client$(printf '%02d' $i); done
echo Run the script on all client directories
echo; echo;
find /tmp/ -maxdepth 1 -type d -name 'client*' -exec ./compare_script.sh {}/images {}/movies \;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment