Quiere usar diff
con la opción -s
:
-s, --report-identical-files
report when two files are the same
Tampoco necesita crear un archivo con la salida, solo puede probar al salir del comando diff
:
Check()
{
if [ -e "new.txt" ]
then
rm new.txt
fi
for item in "$2"/*
do
if [ ! -d "$item" ]
then
if diff -s "$1" "$item"
then
echo "$1 $item"
echo "Yes"
fi
fi
done
}
Como señaló Kusalananda, cmp
es probablemente una mejor opción y es más portátil. Podrías usar:
if cmp -s "$1" "$item"
then
echo "$1 $item"
echo "Yes"
fi
Su script parece no usar su primer argumento. Se pasa a la función Iterate
y nunca se vuelve a ver.
Pero el verdadero problema es que ejecuta diff
en cada combinación de dos archivos y luego observa el tamaño de la diferencia. El tamaño de la diferencia no será -cero para archivos que sean diferentes. Por lo tanto, su secuencia de comandos informa Yes
para cada combinación de archivos que son diferentes , no iguales.
También ejecuta innecesariamente la diferencia entre el archivo A
y B
dos veces(A
frente a B
y luego B
frente aA
). Puede solucionar esto generando la lista de archivos solo una vez y luego iterando sobre eso.
Guión alternativo:
#!/bin/sh
if [ ! -d "$1" ]; then
printf 'Usage: %s directory\n' "$0" >&2
exit 1
fi
# set positional parameters to the list of files in the given directory
set -- "$1"/*
# while there's still files to process...
while [ "$#" -gt 0 ]; do
# skip over non-regular files
if [ ! -f "$1" ]; then
shift
continue
fi
# now process the first item in the list against the other ones
item=$1
# shift off the first item from the list
shift
# loop over the remaining items...
for name do
# we're still not interested in non-regular files
[ ! -f "$name" ] && continue
# if they are the same, report this
if cmp -s "$item" "$name"; then
printf '%s and %s has same content\n' "$item" "$name"
fi
done
done
Aún puedes tener tus dos funciones si lo deseas:
#!/bin/sh
if [ ! -d "$1" ]; then
printf 'Usage: %s directory\n' "$0" >&2
exit 1
fi
check () {
# now process the first item in the list against the other ones
item=$1
# shift off the first item from the list
shift
# loop over the remaining items...
for name do
# we're still not interested in non-regular files
[ ! -f "$name" ] && continue
# if they are the same, report this
if cmp -s "$item" "$name"; then
printf '%s and %s has same content\n' "$item" "$name"
fi
done
}
iterate () {
# set positional parameters to the list of files in the given directory
set -- "$1"/*
# while there's still files to process...
while [ "$#" -gt 0 ]; do
# only process regular files
if [ -f "$1" ]; then
check "$@" # checks the first item against the rest
fi
shift # get rid of the first item
done
}
iterate "$1"
Observe cómo no permitimos que la función check
genere su propia lista de archivos. En su lugar, le pasamos la lista de archivos.
Para los vagos:
fdupes -1 /some/directory