Скрипт для поиска и удаления одинаковых файлов по md5:

#!/bin/sh

#TODO - проверить наличие необходимых утилит
#md5
#find
#getopts
#grep

get_yes_no() {
    while [ true ]; do
        echo -n "$1 (Y/N) ? "
        read a
        if [ $? != 0 ]; then
            a='No'
            return
        fi
        case $a in
            [Yy]) a='Yes'; return ;;
            [Nn]) a='No'; return ;;
            *) ;;
        esac
    done
}

build_hash_db() {
# Проверяем существует ли указанный файл БД, если да, то спрашиваем что делать - удалить и создать новый или выйти.
    echo "Запущено построение базы хешей каталога: "$1
    if [ -f "$db_FILE" ]; then
        get_yes_no 'Файл БД уже существует, удалить и создать новый?'
        [ $a = 'No' ] && echo 'Аварийное завершение.' && exit 1
        [ $a = 'Yes' ] && echo 'Файл БД удален и будет создан заново.' && rm -f "$db_FILE"
    fi

    find "$1" -type f -print | while read file; do
        echo "`md5 -q "$file"`  $file" >> $db_FILE
    done
}

find_and_delete_duplicates_by_hash_from_db(){
    # Если база не создана, то предлагаем создать её.
    echo "Запущен поиск дубликатов в каталоге $1 по базе хешей $db_FILE"
    [ ! -f $db_FILE ] && get_yes_no 'Файл БД не существует, создать новый?'
    [ "$a" = 'No' ] && echo 'Аварийное завершение.' && exit 1
    if [ "$a" = 'Yes' ]; then
        echo 'Создание файла БД: '$db_FILE
        while [ true ]; do
            echo -n 'Введите путь до каталога по которому будет создаваться файл БД: '
            read b
            [ $? != 0 ] && return
            if [ -d $b ]; then
                build_hash_db "$b"
                return
            else
                echo 'Вы ввели неверный путь. Повторите попытку.'
            fi
        done
    fi

    # Ищем дубликаты в каталоге $1 по БД хешей $db_FILE.
    echo '#--------------------------- '`date "+%d.%m.%Y %H:%M:%S"` > ${db_FILE}.log
    find "$1" -type f -print | while read file; do
        hash=`md5 -q "$file"`
        if grep -q $hash $db_FILE ; then
            echo "$file"' is a duplicate and has been removed.'
            echo $hash'     '$file >> "${db_FILE}.log"
            rm -vf "$file"
        fi
    done
}

usage() {
    [ -n "$1" ] && echo "$1"
    cat <<-_EOF
        Usage: 
        -c Режим построения базы хешей.
        -d Режим поиска и удаления повторяющихся файлов на основе построенной ранее базы хешей.
        -f Имя файла БД с хешами, если не будет указан, то будет использоваться значение по умолчанию - file.csv
        -h | --help Справка.

        Пример использования:
        1. Создать базу хешей каталога 1:
            $(basename $0) -c -f my_file.csv /path/to/folder
        2. Найти и удалить дубликаты по созданной базе хешей в каталоге 2:
            $(basename $0) -d -f my_file.csv /path/to/folder
_EOF
    exit 2
}

# Проверяем на пустые аргументы.
[ $# -lt 1 ] && usage

c_FLG=0; d_FLG=0;
while getopts hcdf: a; do
    case "$a" in
        c) [ $d_FLG = 1 ] && usage 'ОШИБКА! Нельзя использовать одновременно опции -c и -d.'; c_FLG=1 ;;
        d) [ $c_FLG = 1 ] && usage 'ОШИБКА! Нельзя использовать одновременно опции -c и -d.'; d_FLG=1 ;;
        f) db_FILE="$OPTARG" ;;
        ?|h) usage ;;
    esac
done

# Сдвигаем ряд аргументов на количество уже разобранных аргументов и оставляем последний.
shift $(($OPTIND-1)) #shift `expr  $OPTIND - 1`

# Проверка аргументов и важных переменных.
[ -z "$1" ] && usage 'ОШИБКА! Не задан каталог для обработки.'
[ -z "$db_FILE" ] && usage 'ОШИБКА! Не задана опция -f.'
[ $c_FLG = 0 -a $d_FLG = 0 ] && usage 'ОШИБКА! Не указана ни одна из опций -c или -d.'

# Запуск фукций в зависимости от установленных переменных.
[ "$c_FLG" = 1 ] && build_hash_db "$1"
[ "$d_FLG" = 1 ] && find_and_delete_duplicates_by_hash_from_db "$1"

Comments

comments powered by Disqus