1

Я хочу написать скрипт для поиска дубликатов файлов в заданном каталоге и удаления копии в зависимости от хеш-кода. Когда я запускаю скрипт, он удаляет копию и исходный файл.

Вот мой код:

#!/bin/bash
a=1;
b=0;
c=1;

while true
do
echo "Enter the directory:"
read directory
if [ -d $directory ]; then
break
else
echo "Invalid directory"
fi
done

for FILE in `ls $directory`
do
b=`expr $b + $a`
if [ $b -gt 2 ]
then
h= `md5sum $directory/$FILE | awk '{ print $1 }'`
a=0;
for f in `ls $directory`
do
a=`expr $a + $c`
if [ $a -gt 2 ]
then
s= `md5sum $directory/$FILE | awk '{ print $1 }'`
if [ "$f" == "$FILE" ]
then
break
else
if [ "$s" = "$h" ]
then
rm -rf $directory/$FILE
fi
fi    
fi
done
fi
done

1 ответ1

1

Ваши сценарии получают первый файл в каталоге и сравнивают его со всеми файлами, таким образом, первый файл проверяется на наличие самого себя. Который вернет тот же хеш MD5. Потому что $FILE и $f абсолютно одинаковы. Вы должны изменить скрипт для сравнения только файлов и избегать сравнения файлов с самим собой:

#!/bin/bash
while true
do
  echo "Enter the directory:"
  read directory
  if [ -d $directory ]; then
    break
  else
    echo "Invalid directory"
  fi
done

for FILE in `ls $directory`
do
  if [ ! -f $FILE ]; then
    break;
  fi
  h=`md5sum $directory/$FILE | awk '{ print $1 }'`
  for f in `ls $directory`
  do
    if [ -f $f ] && [ $FILE != $f ]; then
      s=`md5sum $directory/$f | awk '{ print $1 }'`
      if [ "$s" = "$h" ]; then
        echo Removing $f
        rm -rf $directory/$f
      fi
    fi
  done
done

Тем не менее, вы можете найти два разных файла, которые выдают один и тот же MD5-хеш. Это не просто и не легко, но, конечно, не невозможно. Таким образом, этот скрипт может удалить два разных файла, "думая", что они имеют одинаковое содержимое.

Более безопасный сценарий будет таким:

#!/bin/bash
while true
do
  echo "Enter the directory:"
  read directory
  if [ -d $directory ]; then
    break
  else
    echo "Invalid directory"
  fi
done

for FILE in `ls $directory`
do
  if [ ! -f $FILE ]; then
    break;
  fi
  for f in `ls $directory`
  do
    if [ -f $f ] && [ $FILE != $f ]; then
      cmp -s $directory/$FILE $directory/$f
      if [ "$?" -eq 0 ] ; then
        echo Removing $f
        rm -rf $directory/$f
      fi
    fi
  done
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .