Преобразование идентичных файлов в hardlinks

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

Мне кажется, что для значительной части музыки нет разницы между двумя экземплярами – обычно, когда распределенная версия доступна только в формате mp3 / ogg и не имеет встроенных обложек. Пространство на жестком диске может быть дешевым, но это не повод тратить его. Есть ли способ сценария:

  1. Проверить идентичные файлы в двух каталогах
  2. Когда найдены одинаковые файлы, замените их на жесткую ссылку на другую
  3. Без, например, времени, чтобы получить полный разброс, в интересах времени
  4. Но все же без риска случайного удаления копии двух неидентичных файлов, что является удаленным, но отличным от нуля шансом, если я хотел бы, например, сравнить хэши?

  • удобный скрипт для сокращения количества ссылок на hardlink?
  • Есть ли лучший способ, чем cp, копировать миллионы файлов при сохранении жестких ссылок?
  • Может ли жесткая связь нарушить структуру файловой системы?
  • Почему жесткие ссылки на каталоги не разрешены в UNIX / Linux?
  • Есть ли инструмент для создания жесткой ссылки на несвязанный индексный дескриптор?
  • Параметр -link-dest от rsync не связан из-за времени файла
  • Как restorecon обрабатывает ссылки?
  • Недопустимая ссылка между устройствами в режиме Hardlinking в той же файловой системе
  • 2 Solutions collect form web for “Преобразование идентичных файлов в hardlinks”

    Следующее использует 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 для безопасности. Запустите его один раз, чтобы узнать, что произойдет, и удалите его и запустите снова, если вы уверены, что он поступает правильно.

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

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

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

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

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

    Interesting Posts

    Удалите установленный вручную драйвер (беспроводной USB)

    Безопасно ли добавлять. к моей ПУТЬ? Как так?

    Исправить файловую оболочку

    Ошибка в lpr, но принтер не печатает

    Как автоматически создавать файл .desktop?

    Полностью удалить Grub с компьютера

    Как запустить мою собственную программу без указания ее пути

    Когда использовать человека и человека -k для проверки страниц руководства?

    «Совместное использование экрана» в командной строке?

    Что такое эквивалент Debian для Ubuntu Core / Base?

    Проблема блокировки брандмауэра портов NFS

    Как установить и установить новые темы в плазме KDE через терминал

    Приостановить QEMU / KVM VM (сохранить RAM и состояние процессора на диск), например, vmware Player?

    Запуск приложения GUI в фоновом режиме и последующее повторное подключение

    Возможно ли, что * можно напрямую украсть закрытый ключ, если он не использует кодовую фразу?

    Linux и Unix - лучшая ОС в мире.