Чи є простий спосіб замінити повторювані файли жорсткими посиланнями?


136

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

Ось така ситуація: це файловий сервер, на якому кілька людей зберігають аудіофайли, кожен користувач має свою папку. Іноді у кількох людей є копії таких самих аудіофайлів. Зараз це дублікати. Я хотів би зробити так, щоб вони були жорсткими посиланнями, щоб заощадити місце на жорсткому диску.


20
Одна з проблем, з якою ви можете зіткнутися з жорсткими посиланнями, полягає в тому, що якщо хтось вирішить зробити щось із одного зі своїх музичних файлів, які ви жорстко пов’язані, вони можуть ненавмисно вплинути на доступ інших людей до їх музики.
Стівен D

4
Ще одна проблема полягає в тому, що два різних файли, що містять "Деяку дійсно велику мелодію", навіть якщо вони взяті з одного джерела з тим же кодером, швидше за все, не будуть однаковими по бітах.
msw

3
краще роздумом може бути папка загальнодоступної музики ...
Стефан


1
@tante: Використання посилань не вирішує жодних проблем. Коли користувач "видаляє" файл, кількість посилань на нього зменшується, коли кількість досягає нуля, файли дійсно видаляються, ось і все. Таким чином, видалення не є проблемою із жорстко пов’язаними файлами, єдина проблема - це користувач, який намагається редагувати файл (справді непросто), або перезаписати його (цілком можливо, якщо увійти в систему).
maaartinus

Відповіді:


41

На http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl є сценарій perl, який робить саме те, що ви хочете:

Проходьте всі каталоги, названі в командному рядку, обчисліть контрольні суми MD5 та знайдіть файли з однаковим MD5. Якщо вони рівні, зробіть реальне порівняння, якщо вони дійсно рівні, замініть другий з двох файлів міцним посиланням на перший.


Звучить ідеально , дякую !! Я спробую це і прийму, якщо він працює, як описано!
Джош

3
Це робилося саме те, про що я просив. Однак я вважаю, що ZFS з дедупсією врешті-решт стане способом зробити, оскільки я виявив, що файли мали невеликі відмінності, тому лише декілька можуть бути жорсткими посиланнями.
Джош

11
Виступив із цим, але вивчивши ще декілька, я цього не зробив. rdfindдоступний за допомогою менеджерів пакетів для ВСІХ основних платформ (os x, linux, (cyg) win, solaris), і працює з високою швидкістю. Тож перевірте відповідь нижче.
олігофрен

@oligofren Я думав так само, але потім вдарив [Errno 31] Too many links. Цей скрипт, здається, єдине, що справляється з цим.
phunehehe

5
Перевірка суми кожного окремого файлу, а не лише файлів, де існує хоча б один з однаковим розміром, є надмірно неефективною (і зайво схильною до хеш-колізій).
Чарльз Даффі

85

rdfindробить саме те, що ви просите (і в порядку Джоні, чому списки). Дозволяє видаляти дублікати, замінювати їх м'якими або жорсткими посиланнями. У поєднанні з symlinksвами також можна зробити символьне посилання абсолютним або відносним. Можна навіть вибрати алгоритм контрольної суми (md5 або sha1).

Оскільки вона компілюється, це швидше, ніж у більшості сценаріїв: timeу папці 15 GiB з 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 швидше, ніж duff і fslint.
Даніель Треббіен

ооо, приємно. Раніше я використовував fdupes, але в останній Ubuntu 14.10 відсутня його опція -L для твердих ліній. Був досить повільним і не існував для Homebrew на OSX, тому ця відповідь є набагато кращою. Дякую!
олігофрен

Дуже розумний і швидкий алгоритм.
ndemou

2
Я підозрюю, що ефективність цього інструмента має більше спільного з самим алгоритмом і менше стосується того, чи це компільований інструмент, чи сценарій. Для такого роду операцій диск буде збиратися вузьким місцем майже весь час. Поки сценарії інструментів переконуються, що вони виконують операцію асинхронізації вводу / виводу під час запису процесора на контрольних сум, вони повинні виконувати як і власний двійковий файл.
cdhowie

rdfind дуже залежить від нової ОС та компілятора. (не запускається на CentOS 6.x без майже повного відновлення інструментів розробки)
Cosmo F

49

Використовуйте fdupesінструмент:

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


filename1
filename2

filename3
filename4
filename5


при цьому ім'я файлу1 та ім’я2 однакові, а ім’я файлу3, ім’я файлу4 та ім’я файлу5 однакові.


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Здається, лише знайдіть дублікати, а не замініть їх жорсткими посиланнями, тому не є відповіддю на питання ІМО.
Калімо

2
Існує аналогічний інструмент, який називається jdupes, на основі якого fdupes, але він також може замінити дублікати файлів символьними посиланнями ( -l), жорсткими посиланнями ( -L) або доручити btrfs дедублювати блоки на рівні файлової системи ( -Bякщо ви використовуєте btrfs).
Маріус Гедмінас

23

Я використовую hardlinkз http://jak-linux.org/projects/hardlink/


1
Хороший натяк, я використовую на регулярній основі code.google.com/p/hardlinkpy , але це не був оновлений на деякий час ...
meduz

2
Це схоже на оригінал hardlinkу Fedora / RHEL / тощо.

1
hardlinkтепер є основним двійковим кодом у багатьох пакетних системах Linux (з ~ 2014 р.) і надзвичайно швидко. Для 1,2-мільйонних файлів (320 ГБ) потрібно лише 200 секунд (зв'язавши приблизно 10% файлів).
Марсель Вальдвогель

FWIW, вищезгадане hardlinkбуло створено Джуліаном Андресом Клоде, тоді як Fedora hardlinkстворив Якуб Єлінек (джерело: pagure.io/hardlink - назва пакету Fedora: hardlink)
maxschlepzig

18

Це одна з функцій, які надає "fslint" - http://en.flossmanuals.net/FSlint/Introduction

Натисніть кнопку "Об’єднати":

Знімок екрана


4
Them

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 має підтримку дедуплікації.
hhaamu

14
ZFS дедуп - нікому не друг. Там, де ZFS рекомендує 1 Гб оперативної пам’яті на 1 Tb, що займає дисковий простір, ви страшні горіхи, якщо намагаєтесь використовувати дедуппію менше ніж 32 ГБ оперативної пам’яті на 1 Тб використаного місця на диску. Це означає, що для дзеркала 1 Тб, якщо у вас немає 32 Гб оперативної пам’яті, ви, швидше за все, рано чи пізно зіткнетеся з умовами бомби пам’яті, які зупинять машину через відсутність оперативної пам’яті. Був там, зробив це, все-таки одужаючи від ПТСР.
вбивця

4
Щоб уникнути надмірних вимог оперативної пам’яті за допомогою дедуплікації в Інтернеті (тобто, перевіряйте кожне записування), btrfsвикористовуйте пакетну чи офлайн- дедуплікацію (запустіть її, коли вважаєте це корисним / необхідним) btrfs.wiki.kernel.org/index.php/Deduplication
Марсель Вальдвогель

3
Оновлення через сім років: я врешті-решт перейшов до ZFS і спробував дедуплікацію - я виявив, що вимоги до оперативної пам’яті дійсно були дуже високими. Хитро використання знімків ZFS забезпечило рішення, яке я в кінцевому підсумку використав. (Скопіюйте музику, знімок та клонуйте одного користувача, скопіюйте музику другого користувача в клон, використовуючи rsync --inplaceлише збережені змінені блоки)
Джош

7

У сучасному Linux сьогодні є https://github.com/g2p/bedup, який дедублює файлову систему btrfs, але 1) без великої кількості накладних сканувань, 2) файли можуть легко розходитись згодом.


1
Довідкова інформація та додаткова інформація наведені на btrfs.wiki.kernel.org/index.php/Deduplication (включаючи посилання cp --reflink, див. Також нижче)
Marcel Waldvogel,

5

Для пошуку дублікатів файлів можна використовувати duff .

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

Просто запустіть:

duff -r target-folder

Щоб автоматично створити жорсткі посилання на ці файли, вам потрібно буде розібрати вихід duff з bash або іншою мовою сценаріїв.


Дійсно повільно, проте - див. Rdfind.pauldreik.se/#g0.6
ndemou

5
aptitude show hardlink

Опис: Жорсткі посилання декількох копій одного файлу Hardlink - це інструмент, який виявляє кілька копій одного файлу та замінює їх жорсткими посиланнями.

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


Єдина згадана тут програма, доступна для Gentoo без розмахування та з підтримкою жорсткого посилання, дякую!
Хорріт Шипперс

4

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

   --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.

Думаю, я оновлю свій cpпсевдонім, щоб завжди включати --reflink=autoпараметр
Marcos

1
Чи підтримує ext4 справді --reflink?

7
Це підтримується на btrfs та OCFS2. Це можливо лише у файлових системах копіювання під час запису, яких ext4 немає. btrfs дійсно формується. Я люблю використовувати його через рефлінк та знімки, робить вас менш бояться робити масові операції на великих деревах файлів.
clacke

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, ось баш-версія:

#!/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" Просто замінює дублікат файлу жорстким посиланням, щоб ви могли замість нього змінити rm на $ NEWFILE.
seren

і як у наступному рядку запишіть у якийсь текстовий файл якось $ OLDFILE-> NEWFILE ???
MR.GEWA

Ага, правильно. Так, додайте рядок після rm, наприклад: echo "$ NEWFILE" >> /var/log/deleted_duplicate_files.log
seren

2
Не вигадуйте колесо заново. Є більш зрілі рішення, наприклад rdfind, що працює з натурною швидкістю і просто вимагає brew install rdfindабо apt-get install rdfindвстановлюється.
олігофрен

1

Я створив сценарій Perl, який робить щось подібне до того, про що ви говорите:

http://pastebin.com/U7mFHZU7

По суті, він просто проходить каталог, обчислюючи SHA1суму файлів у ньому, хешируя його і зв'язуючи збіги разом. Це корисно в багатьох, багатьох випадках.


2
Я сподіваюсь скоріше спробувати це ... чому б не завантажити його на CPAN ... Додаток ::
relink

2
@xenoterracide: через всі подібні та зріліші рішення, які вже існують. див. інші відповіді, особливо rdfind.
олігофрен

1
@oligofren Я не сумніваюся, що кращі рішення існують. Гадаю, TMTOWTDI.
амфетамахін

1

Якщо ви хочете замінити дублікати жорсткими посиланнями на mac або будь-якій системі UNIX, ви можете спробувати SmartDupe http://sourceforge.net/projects/smartdupe/ я його розробляю


3
Чи можете ви розширити, наскільки "розумний" це?
Стефан Гіменез

1
Як я можу порівняти файли двох різних каталогів?
Буркардо

1

Програми FSLint ( http://www.pixelbeat.org/fslint/ ) можуть знайти всі рівні файли у будь-якій папці (за вмістом) та створити жорсткі посилання. Спробувати!

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


Він висить скануючи 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/Comppare_of_file_systems , спеціально за таблицею Особливості та дедуплікація даних стовпців. Ви можете натиснути на нього і сортувати :)

Особливо подивіться на файлову систему ZFS. Це доступно як FUSE, але таким чином це дуже повільно. Якщо вам потрібна підтримка, перегляньте сторінку http://zfsonlinux.org/ . Потім потрібно виправити ядро, а потім встановити інструменти zfs для управління. Я не розумію, чому 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. Можливо, це краще для вас :)


1
Мені подобається офлайн (або пакетний ) дедуплікаційний підхід btrfs. Чудове обговорення варіантів (включаючи cp --reflinkопцію) тут: btrfs.wiki.kernel.org/index.php/Deduplication
Марсель Вальдвогель

ZFS не є Solaris або OpenSolaris. Він підтримується у FreeBSD. Крім того , ZFS на Linux є драйвер пристрою на основі; ZFS на FUSE - різна річ.
KJ Зеефрід

0

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

Моїм рішенням було б створити "загальний" файл у прихованій папці та замінити фактичні дублікати символічними посиланнями ... тоді символічні посилання будуть вбудовані у метадані чи альтернативні потоки файлів, які записують лише два "файли". відрізняються одна від одної, наприклад, якщо одна людина хоче змінити ім’я файлу або додати власну обкладинку альбому чи щось подібне; це може бути корисним навіть поза програмами баз даних, як-от встановлення декількох версій однієї гри або програмного забезпечення та тестування їх незалежно навіть з найменшими відмінностями.


0

Найпростіший спосіб - використовувати спеціальну програму dupeGuru

Скріншот налаштувань dupeGuru

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

Параметри видалення

Ці параметри впливають на те, як відбувається повторне видалення. У більшості випадків не потрібно вмикати жоден із них.

Пов’язати видалені файли:

Видалені файли замінюються посиланням на довідковий файл. У вас є вибір замінити його або символьним, або жорстким. ... символьне посилання - це ярлик до шляху файлу. Якщо вихідний файл видалено або переміщено, посилання розривається. Жорстке посилання - це посилання на сам файл. Це посилання настільки ж добре, як і "реальний" файл. Лише коли всі тверді посилання на файл видаляються, сам файл видаляється.

В OSX та Linux ця функція підтримується повністю, але в Windows це трохи складніше. Windows XP не підтримує його, але Vista і вище підтримують його. Однак, щоб функція працювала, dupeGuru повинен працювати з адміністративними привілеями.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.