Преобразование идентичных файлов в жесткие ссылки [дубликат]

Я делаю полные резервные копии системных дисков с помощью dd . Это самый простой способ, который я знаю.

Загрузитесь с USB, затем выполните dd if = / dev / sda of = / external / connected / storage / my_server_backup.img conv = sync bs = 8M && sync и выпейте кофе, так как это может занять некоторое время.

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

1
27.05.2017, 21:40
2 ответа

Если у вас нет большой коллекции очень похожих файлов, вычисление и сравнение хэшей не ускорит процесс поиска дубликатов. Самая медленная операция — чтение с диска. Вычисление хэша означает чтение всего файла, а также это задача с интенсивным использованием ЦП с современными криптографически стойкими хэшами.

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

Вот почему я бы порекомендовал сделать рекурсивный список каталогов, подготовив список длины + пути, затем отсортировать список по числам и, наконец, работать только с наборами файлов одинаковой длины, сравнивая их попарно. Если два файла совпадают, один из них можно заменить жесткой ссылкой.

2
27.01.2020, 23:19

В следующем примере используется md5 для создания дайджеста MD5 для всех файлов в текущем каталоге или ниже:

find . -type f -exec md5 {} +

Замените md5 на md5sum --tag. ], если у вас нет утилиты BSD md5.

Давайте создадим простой скрипт, чтобы сделать это с каталогами:

#!/bin/bash

tmpdir=${TMPDIR:-/tmp}

if (( $# != 2 )); then
    echo 'Expected two directories as arguments' >&2
    exit 1
fi

i=0
for dir in "$@"; do
    (( ++i ))
    find "$dir" -type f -exec md5 {} + | sort -t '=' -k2 -o "$tmpdir/md5.$i"
done

Он берет два каталога в командной строке и создает файлы с именами md5.1 и md5.2, по одному файлу для каждого каталога в /tmp (или куда указывает $TMPDIR). Эти файлы отсортированы по дайджесту MD5.

Файлы будут выглядеть как

MD5 (<path>) = <MD5 digest>

с одной такой строкой для каждого файла.

Затем в том же скрипте сравните контрольную сумму между двумя файлами:

join -t '=' -1 2 -2 2 "$tmpdir"/md5.[12]

Это выполняет реляционную операцию «соединения» между двумя файлами, используя контрольную сумму в качестве поля соединения. Любые строки, имеющие одинаковую контрольную сумму в двух полях, будут объединены и выведены.

Если какая-либо контрольная сумма одинакова в обоих файлах, будет выведено:

<space><MD5 digest>=MD5 (<path1>) =MD5 (<path2>)

Это может быть передано в awk напрямую для разбора двух путей:

awk -F '[()]' 'BEGIN { OFS="\t" } { print $2, $4 }'

-F [()] — это просто способ сказать, что мы хотели бы разделить каждую строку на поля на основе ( и ). Это оставляет нам пути в полях 2 и 4.

Это выведет

<path1><tab><path2>

Тогда остается просто прочитать эти пары путей, разделенных табуляцией, и ввести правильные команды для создания ссылок:

while IFS=$'\t' read -r path1 path2; do
    echo ln -f "$path1" "$path2"
done

В резюме:

#!/bin/bash

tmpdir=${TMPDIR:-/tmp}

if (( $# != 2 )); then
    echo 'Expected two directories as arguments' >&2
    exit 1
fi

i=0
for dir in "$@"; do
    (( ++i ))
    find "$dir" -type f -exec md5 {} + | sort -t '=' -k2 -o "$tmpdir/md5.$i"
done

join -t '=' -1 2 -2 2 "$tmpdir"/md5.[12] |
awk -F '\\)|\\(' 'BEGIN { OFS="\t" } { print $2, $4 }' |
while IFS=$'\t' read -r path1 path2; do
    echo ln -f "$path1" "$path2"
done

rm -f "$tmpdir"/md5.[12]

echo в цикле while служит для безопасности.Запустите его один раз, чтобы посмотреть, что произойдет, и удалите его и запустите снова, если вы уверены, что он работает правильно.

Помните, что жесткие ссылки не могут охватывать разделы. Это означает, что оба каталога должны находиться на одном разделе. Файлы во втором втором каталоге будут перезаписаны, если будут обнаружены дубликаты. Держите где-нибудь резервную копию оригиналов, пока не будете довольны результатом!

Обратите внимание, что это решение не будет работать должным образом, если какой-либо файл имеет ( или ) или вкладку в имени файла.

3
27.01.2020, 23:19

Теги

Похожие вопросы