Есть ли простой способ заменить дубликаты файлов жесткими ссылками?

137

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

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

мистифицировать
источник
20
Одна из проблем, с которой вы можете столкнуться с жесткими ссылками, заключается в том, что если кто-то решит сделать что-то с одним из своих музыкальных файлов, с которыми вы жестко связаны, они могут непреднамеренно повлиять на доступ других людей к своей музыке.
Стивен Д
4
Другая проблема заключается в том, что два разных файла, содержащие «Some Really Great Tune», даже если они взяты из одного и того же источника с одним и тем же кодировщиком, скорее всего, будут не одинаковыми по битам.
MSS
3
Лучшее решение может быть иметь общую папку с музыкой ...
Стефан
4
относящиеся: superuser.com/questions/140819/ways-to-deduplicate-files
Дэвид Кэри
1
@tante: Использование символических ссылок не решает проблемы. Когда пользователь «удаляет» файл, количество ссылок на него уменьшается, когда количество достигает нуля, файлы действительно удаляются, вот и все. Таким образом, удаление не является проблемой с жестко связанными файлами, единственная проблема - это пользователь, пытающийся отредактировать файл (действительно непробиваемый) или перезаписать его (вполне возможно при входе в систему).
Maaartinus

Ответы:

41

На http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl есть скрипт на Perl, который делает именно то, что вы хотите:

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

fschmitt
источник
Звучит отлично , спасибо! Я попробую это и приму, если это работает как описано!
Джош
3
Это именно то, что я просил. Однако я верю, что ZFS с дедупликацией в конечном итоге будет подходить, так как я обнаружил, что файлы имеют небольшие различия, так что только некоторые из них могут быть жестко связаны.
Джош
11
Проголосовал за это, но после исследования, я вроде как не сделал. rdfindдоступен через менеджеры пакетов для ВСЕХ основных платформ (os x, linux, (cyg) win, solaris) и работает с невероятной скоростью. Так что проверьте ответ ниже.
олигофрен
@oligofren Я тоже так думал, но потом ударил [Errno 31] Too many links. Эти скрипы, кажется, единственная вещь, которая справляется с этим.
phunehehe
5
Контрольная сумма каждого отдельного файла, а не только файлов, где существует хотя бы один другой файл с одинаковым размером, излишне неэффективна (и излишне подвержена коллизиям хеша).
Чарльз Даффи
85

rdfindделает именно то, что вы просите (и в порядке johny, почему списки). Позволяет удалять дубликаты, заменять их мягкими или жесткими ссылками. В сочетании с symlinksвами также можно сделать символическую ссылку либо абсолютной, либо относительной. Вы даже можете выбрать алгоритм контрольной суммы (md5 или sha1).

Поскольку он скомпилирован, он работает быстрее, чем большинство решений timeна основе сценариев: для папки с 15 ГБ с 2600 файлами на моем Mac Mini с 2009 года возвращается

9.99s user 3.61s system 66% cpu 20.543 total

(используя md5).

Доступно в большинстве обработчиков пакетов (например, MacPorts для Mac OS X).

децибел
источник
11
+1 Я использовал rdfindи любил это. У этого есть -dryrun trueопция, которая сообщит вам, что он сделал бы. Замена дубликатов жесткими ссылками так же проста, как и -makehardlinks true. Это произвело хороший журнал, и это дало мне знать, сколько места было освобождено. Кроме того , в соответствии с авторским эталоном , rdfind быстрее , чем подстилки и FSlint.
Даниэль Треббиен
ооо, мило Раньше я использовал fdupes, но в последней версии Ubuntu 14.10 его опция -L для жестких ссылок на дупс отсутствует. Был довольно медленным и не существовал для Homebrew на OSX, так что этот ответ намного лучше. Спасибо!
oligofren
Очень умный и быстрый алгоритм.
ndemou
2
Я подозреваю, что производительность этого инструмента больше связана с самим алгоритмом, а не с скомпилированным инструментом или скриптом. Для такого рода операций диск будет узким местом почти все время. Пока скриптовые инструменты гарантируют, что они выполняют асинхронную операцию ввода-вывода во время прожига ЦП на контрольных суммах, они должны работать примерно так же, как и собственный двоичный файл.
cdhowie
rdfind очень зависит от новой ОС и компилятора. (не будет работать на CentOS 6.x без почти полной перестройки инструментов разработки)
Cosmo F
49

Используйте fdupesинструмент:

fdupes -r /path/to/folderвыдает список дубликатов в каталоге (-r делает его рекурсивным). Вывод выглядит так:


имя
файла1 имя файла2

имя
файла3
имя файла4 имя файла5


с именами filename1 и filename2 идентичны, а filename3, filename4 и filename5 также идентичны.

Tante
источник
1
Примечание Ubuntu: По состоянию на сентябрь 2013 года, у него не было стабильного релиза (он находится на 1.50-PR2-3), поэтому обновление еще не появилось в ubuntu.
Стюарт Аксон
11
Я только что попытался установить fdupes_1.50-PR2-4 на Ubuntu и Debian, и ни один из них не имеет флаг -L. К счастью, сборка с github.com/tobiasschulz/fdupes была супер легкой.
neu242
3
Попробуйте rdfind- как fdupes, но быстрее и доступно на OS X и Cygwin.
олигофрен
6
fdupesКажется, только найти дубликаты, а не заменить их жесткими ссылками, поэтому не ответ на вопрос IMO.
Calimo
2
Существует аналогичный инструмент, jdupesкоторый основан на этом fdupes, но он также может заменить дубликаты файлов на symlinks ( -l), hardlinks ( -L) или дать команду btrfs дедуплицировать блоки на уровне файловой системы ( -Bесли вы используете btrfs).
Мариус Гедминас
23

Я использую hardlinkот http://jak-linux.org/projects/hardlink/

waltinator
источник
1
Хороший совет, я использую на регулярной основе code.google.com/p/hardlinkpy, но это некоторое время не обновлялось ...
meduz
2
Это похоже на оригинал hardlinkна Fedora / RHEL / и т. Д.
1
hardlinkтеперь является родным двоичным файлом во многих системах пакетов Linux (с ~ 2014 года) и чрезвычайно быстр. Для 1,2M файлов (320 ГБ) это заняло 200 секунд (связывание примерно 10% файлов).
Марсель Вальдвогель
Кстати, вышесказанное hardlinkбыло создано Джулианом Андресом Клодом, а Fedora hardlink- Якубом Елинеком (источник: pagure.io/hardlink - Имя пакета Fedora: hardlink)
maxschlepzig
18

Это одна из функций, предоставляемых "fslint" - http://en.flossmanuals.net/FSlint/Introduction

Нажмите кнопку «Объединить»:

Скриншот

Флимм
источник
4
-M будет жестко связывать дубликаты вместе, -d удалит все, кроме одного, и -t запустит
пробный
1
В Ubuntu вот что нужно сделать: sudo apt-get install fslint /usr/share/fslint/fslint/findup -m /your/directory/tree(каталог / usr / share / fslint / fslint / по умолчанию не находится в $ PATH)
Jocelyn
14

Поскольку ваша основная цель - сэкономить дисковое пространство, существует другое решение: дедупликация (и, возможно, сжатие) на уровне файловой системы. По сравнению с решением с жесткой связью, оно не имеет проблемы непреднамеренного воздействия на другие связанные файлы.

ZFS имеет дедупликацию (на уровне блоков, а не на уровне файлов) с версии пула 23 и сжатие с давних времен. Если вы используете Linux, вы можете попробовать zfs-fuse , или, если вы используете BSD, он изначально поддерживается.

Вэй-Инь
источник
Это, вероятно, тот путь, по которому я в конечном итоге пойду, однако разве реализация BSD ZFS делает дедупликацию? Я думал, что нет.
Джош
Кроме того, файловая система HAMMER в DragonFlyBSD поддерживает дедупликацию.
Хааму
14
Дедупс ZFS - друг никого. В тех случаях, когда ZFS рекомендует 1 ГБ оперативной памяти на 1 ТБ используемого дискового пространства, вы чертовски тупы, если пытаетесь использовать дедупликацию с менее чем 32 ГБ оперативной памяти на 1 ТБ используемого дискового пространства. Это означает, что для зеркала объемом 1 ТБ, если у вас нет оперативной памяти 32 ГБ, вы, вероятно, рано или поздно столкнетесь с условиями бомбы памяти, которые остановят машину из-за отсутствия оперативной памяти. Был там, сделал это, все еще оправлялся от ПТСР.
убийца
4
Чтобы избежать чрезмерных требований к оперативной памяти при онлайн-дедупликации (т. Е. Проверять каждую запись), btrfsиспользует пакетную или автономную дедупликацию (запускайте ее всякий раз, когда вы считаете это полезным / необходимым) btrfs.wiki.kernel.org/index.php/Deduplication
Marcel Waldvogel
3
Обновление семь лет спустя: в конце концов я перешел на ZFS и попробовал дедупликацию - я обнаружил, что требования к оперативной памяти были слишком высокими. Лукавое использование снимков ZFS обеспечило решение, которое я в итоге использовал. (Скопируйте музыку, снимок и клон одного пользователя, скопируйте музыку второго пользователя в клон, используя rsync --inplaceтолько сохраненные блоки)
Josh
7

В настоящее время в современном Linux есть https://github.com/g2p/bedup, который дедуплицирует в файловой системе btrfs, но 1) без лишних затрат на сканирование, 2) после этого файлы могут легко снова расходиться.

Мэтью Блох
источник
1
Общая информация и дополнительная информация указана на сайте btrfs.wiki.kernel.org/index.php/Deduplication (включая ссылку cp --reflink, см. Также ниже)
Марсель Вальдвогель,
5

Для поиска дубликатов файлов вы можете использовать duff .

Duff - это утилита командной строки Unix для быстрого поиска дубликатов в заданном наборе файлов.

Просто запустите:

duff -r target-folder

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

Стефан
источник
Хотя очень медленно - см. Rdfind.pauldreik.se/#g0.6
ndemou
5
aptitude show hardlink

Описание: Жесткие ссылки на несколько копий одного и того же файла Жесткая ссылка - это инструмент, который обнаруживает несколько копий одного и того же файла и заменяет их жесткими ссылками.

Идея была взята с http://code.google.com/p/hardlinkpy/ , но код был написан с нуля и лицензирован по лицензии MIT. Домашняя страница: http://jak-linux.org/projects/hardlink/

Жюльен Палар
источник
Единственная упомянутая здесь программа доступна для Gentoo без демаскирования и с поддержкой жестких ссылок, спасибо!
Йоррит Шипперс
4

Я использовал многие из инструментов жестких ссылок для Linux, упомянутых здесь. Я тоже застрял с ext4 fs в Ubuntu и использую его cp -l и -s для жесткого / softlinking. Но в последнее время заметил облегченную копию на странице man cp , которая подразумевала бы резервирование избыточного дискового пространства, пока одна сторона не будет изменена:

   --reflink[=WHEN]
          control clone/CoW copies. See below

       When  --reflink[=always]  is specified, perform a lightweight copy, where the 
data blocks are copied only when modified.  If this is not possible the
       copy fails, or if --reflink=auto is specified, fall back to a standard copy.
Marcos
источник
Я думаю, что я обновлю свой cpпсевдоним, чтобы всегда включать --reflink=autoпараметр сейчас
Marcos
1
Ext4 действительно поддерживает --reflink?
7
Это поддерживается на btrfs и OCFS2. Это возможно только в файловых системах копирования при записи, которых нет у ext4. btrfs действительно улучшается. Мне нравится использовать его из-за reflink и моментальных снимков, поэтому вы меньше боитесь выполнять массовые операции с большими деревьями файлов.
Клак
3

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

  • имя файла
  • размер
  • контрольная сумма md5
  • содержимое байта

Есть ли какие-либо методы сделать это? Посмотрите duff, fdupes, rmlint, fslintи т.д.

На сайте commandlinefu.com проголосовали следующие методы : Найти дубликаты файлов (сначала по размеру, а затем по хешу MD5)

Можно ли добавить сравнение имени файла в качестве первого шага, а размер - в качестве второго шага?

find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | \
  xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | \
  sort | uniq -w32 --all-repeated=separate
Джонни почему
источник
3
Я использовал duff, fdupesи rmlint, и настоятельно рекомендую читателям взглянуть на третий из них . У него отличный набор опций (и документация). Благодаря этому я смог избежать большого количества постобработки, которую мне нужно было использовать с другими инструментами.
Субъект
3
В моей практике имя файла является наименее надежным фактором для рассмотрения, и я полностью удалил его из всех моих попыток де-дупликации. Сколько install.shфайлов можно найти в активной системе? Я не могу сосчитать, сколько раз я сохранял файл и имел конфликт имен, с некоторым переименованием на лету, чтобы сохранить его. Обратная сторона: не знаю, сколько раз я загружал что-то из разных источников, в разные дни, только чтобы обнаружить, что это один и тот же файл с разными именами. (Это также убивает надежность отметки времени.) 1: Размер, 2: Дайджест, 3: Содержимое байта.
Цыганка
@GypsySpellweaver: (1) зависит от личного варианта использования, вы не согласны? В моем случае у меня есть несколько восстановлений из нескольких резервных копий, где файлы с одинаковым именем и содержимым существуют в разных папках восстановления. (2) Ваш комментарий предполагает сравнение только имени файла . Я не предлагал устранить другие проверки.
Джонни, почему
2

Так как я не фанат Perl, вот версия bash:

#!/bin/bash

DIR="/path/to/big/files"

find $DIR -type f -exec md5sum {} \; | sort > /tmp/sums-sorted.txt

OLDSUM=""
IFS=$'\n'
for i in `cat /tmp/sums-sorted.txt`; do
 NEWSUM=`echo "$i" | sed 's/ .*//'`
 NEWFILE=`echo "$i" | sed 's/^[^ ]* *//'`
 if [ "$OLDSUM" == "$NEWSUM" ]; then
  echo ln -f "$OLDFILE" "$NEWFILE"
 else
  OLDSUM="$NEWSUM"
  OLDFILE="$NEWFILE"
 fi
done

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

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

ПРИМЕЧАНИЕ. Как упоминалось ранее, жесткие ссылки работают до тех пор, пока файлы никогда не нуждаются в модификации или перемещаются по файловым системам.

Серен
источник
Как я могу изменить ваш скрипт, чтобы вместо жесткой ссылки он просто удалил дубликаты файлов и добавил запись в CSV-файл удаленного файла -> Lined File. , ???
MR.GEWA
Конечно. Жесткая ссылка: echo ln -f "$ OLDFILE" "$ NEWFILE" Просто заменяет дубликат файла жесткой ссылкой, так что вы можете изменить его вместо $ NEWFILE.
Серен
а как на следующей строке записать в какой-нибудь текстовый файл как-то $ OLDFILE-> NEWFILE ???
MR.GEWA
Ааа, верно. Да, добавить строку после rm, например: echo "$ NEWFILE" >> /var/log/deleted_duplicate_files.log
seren
2
Не чертовски изобретай колесо. Доступны более зрелые решения, такие как rdfind, которые работают на родных скоростях и просто требуют brew install rdfindили apt-get install rdfindдолжны быть установлены.
oligofren
1

Я сделал Perl-скрипт, который делает нечто похожее на то, о чем вы говорите:

http://pastebin.com/U7mFHZU7

По сути, он просто пересекает каталог, вычисляя сумму SHA1 файлов в нем, хешируя его и связывая совпадения. Это пригодится во многих, многих случаях.

amphetamachine
источник
2
Я надеюсь, что
скоро попробую
2
@xenoterracide: из-за всех подобных и более зрелых решений, которые уже существуют. смотрите другие ответы, особенно rdfind.
олигофрен
1
@oligofren Я не сомневаюсь, что лучшие решения существуют. TMTOWTDI Я думаю.
амфетамина
1

Если вы хотите заменить дубликаты на Hard Links на Mac или в любой системе на основе UNIX, вы можете попробовать SmartDupe http://sourceforge.net/projects/smartdupe/, разрабатываю его

ислам
источник
3
Можете ли вы рассказать, насколько это «умно»?
Стефан Гименес
1
Как я могу сравнить файлы двух разных каталогов?
Буркардо
1

Приложение FSLint ( http://www.pixelbeat.org/fslint/ ) может найти все одинаковые файлы в любой папке (по содержанию) и создать жесткие ссылки. Попробуйте!

Хорхе Сампайо

Хорхе HB Сампайо младший
источник
Он зависает при сканировании почти на 1 ТБ жесткого диска ext3, приводит к полному сканированию всей системы. Прервано после 14 часов «поиска»
Angsuman Chakraborty
1

jdupes упоминается в комментарии, но заслуживает отдельного ответа, так как он, вероятно, доступен в большинстве дистрибутивов и работает довольно быстро (он только за одну минуту освободил 2,7 ГБ из 98% заполненных 158 ГБ разделов (накопителей SSD)):

jdupes -rL /foo/bar
Скиппи ле Гран Гуру
источник
0

Если вы будете делать жесткие ссылки, обратите внимание на права на этот файл. Обратите внимание, что владелец, группа, режим, расширенные атрибуты, время и ACL (если вы используете это) хранятся в INODE. Отличаются только имена файлов, поскольку они хранятся в структуре каталогов, а другие указывают на свойства INODE. По этой причине все имена файлов, связанные с одним и тем же узлом, имеют одинаковые права доступа. Вы должны предотвратить изменение этого файла, потому что любой пользователь может повредить файл другим. Это просто. Достаточно, любой пользователь ставит другой файл с тем же именем. Номер инода затем сохраняется, а исходное содержимое файла уничтожается (заменяется) для всех жестко связанных имен.

Лучший способ - дедупликация на уровне файловой системы. Вы можете использовать BTRFS (очень популярный в последнее время), OCFS или подобное. Посмотрите на страницу: https://en.wikipedia.org/wiki/Comparison_of_file_systems , особенно в таблице Характеристики и дедупликация данных столбца. Вы можете нажать на нее и отсортировать :)

Специально посмотрите на файловую систему ZFS. Это доступно как FUSE, но таким образом это очень медленно. Если вам нужна нативная поддержка, посмотрите на страницу http://zfsonlinux.org/ . Затем вы должны исправить ядро, а затем установить zfs tools для управления. Я не понимаю, почему Linux не поддерживает в качестве драйверов, это путь для многих других операционных систем / ядер.

Файловые системы поддерживают дедупликацию двумя способами: дедупликацию файлов или блоков. ZFS поддерживает блокировку. Это означает, что одно и то же содержимое, которое повторяется в одном и том же файле, может быть дедуплицировано. Другой способ - это время, когда данные дедуплицируются, это может быть онлайн (zfs) или автономно (btrfs).

Обратите внимание, дедупликация потребляет оперативную память. Вот почему запись файлов на том ZFS, смонтированный с помощью FUSE, приводит к резкому снижению производительности. Это описано в документации. Но вы можете онлайн включить / выключить дедупликацию на томе. Если вы видите, что какие-либо данные должны быть дедуплицированы, вы просто включаете дедупликацию, переписываете какой-либо файл в любой временный и, наконец, заменяете. после этого вы можете отключить дедупликацию и восстановить полную производительность. Конечно, вы можете добавить в хранилище любые кеш-диски. Это может быть очень быстрый поворот дисков или SSD дисков. Конечно, это могут быть очень маленькие диски. В реальной работе это замена оперативки :)

В Linux вы должны позаботиться о ZFS, потому что не все работают должным образом, особенно когда вы управляете файловой системой, делаете снимок и т. Д., Но если вы конфигурируете и не меняете его, все работает правильно. Другим способом, вы должны изменить linux на opensolaris, он изначально поддерживает ZFS :) Что очень хорошо в ZFS, так это то, что он работает как файловая система, так и менеджер уровней, похожий на LVM. Вам не нужно это, когда вы используете ZFS. Смотрите документацию, если вы хотите узнать больше.

Обратите внимание на разницу между ZFS и BTRFS. ZFS старше и более зрелая, к сожалению, только под Solaris и OpenSolaris (к сожалению, задушена оракулом). BTRFS моложе, но в последнее время очень хорошо поддерживается. Я рекомендую свежее ядро. ZFS имеет дедупликацию онлайн, что приводит к замедлению записи, потому что все рассчитывается онлайн. BTRFS поддерживает автономную дедупликацию. Тогда это экономит производительность, но когда хосту нечего делать, вы периодически запускаете инструмент для дедупликации. И BTRFS изначально создан под Linux. Может быть, это лучше ПС для вас :)

Znik
источник
1
Мне нравится автономный (или пакетный ) подход дедупликации btrfs. Отличное обсуждение вариантов (включая cp --reflinkопцию) здесь: btrfs.wiki.kernel.org/index.php/Deduplication
Марсель Вальдвогель,
ZFS - это не только Solaris или OpenSolaris. Это изначально поддерживается во FreeBSD. Кроме того , ZFS на Linux является драйвер устройства на основе; ZFS на FUSE это совсем другое.
KJ Seefried
0

Жесткие ссылки могут быть не лучшей идеей; если один пользователь изменяет файл, это влияет на оба. Однако удаление жесткой ссылки не удаляет оба файла. Кроме того, я не совсем уверен, занимают ли жесткие ссылки такое же количество места (на жестком диске, а не в ОС), как несколько копий одного и того же файла; согласно Windows (с расширением Link Shell), они делают. Конечно, это Windows, а не Unix ...

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

Amaroq Starwind
источник
0

Самый простой способ - использовать специальную программу dupeGuru

Скриншот настроек dupeGuru

как говорится в документации

Варианты удаления

Эти параметры влияют на способ удаления дубликатов. В большинстве случаев вам не нужно включать ни одну из них.

Ссылка удаленных файлов:

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

В OSX и Linux эта функция поддерживается полностью, но в Windows это немного сложно. Windows XP не поддерживает его, но Vista и выше поддерживают его. Однако, чтобы эта функция работала, dupeGuru должен работать с правами администратора.

Российский младший разработчик Ruby
источник