Как удалить дубликаты файлов с помощью Bash


10

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

Тем не менее, я застрял на том, как это сделать. Что у меня так далеко:

md5 -r * | sort

Который выводит что-то вроде этого:

04c5d52b7acdfbecd5f3bdd8a39bf8fb gordondam_en-au11915031300_1366x768.jpg
1e88c6899920d2c192897c886e764fc2 fortbourtange_zh-cn9788197909_1366x768.jpg
266ea304b15bf4a5650f95cf385b16de nebraskasupercell_fr-fr11286079811_1366x768.jpg
324735b755c40d332213899fa545c463 grossescheidegg_en-us10868142387_1366x768.jpg
3993028fcea692328e097de50b26f540 Soyuz Spacecraft Rolled Out For Launch of One Year Crew.png
677bcd6006a305f4601bfb27699403b0 lechaustria_zh-cn7190263094_1366x768.jpg
80d03451b88ec29bff7d48f292a25ce6 ontariosunrise_en-ca10284703762_1366x768.jpg
b6d9d24531bc62d2a26244d24624c4b1 manateeday_row10617199289_1366x768.jpg
ca1486dbdb31ef6af83e5a40809ec561 Grueling Coursework.jpg
cdf26393577ac2a61b6ce85d22daed24 Star trails over Mauna Kea.jpg
dc3ad6658d8f8155c74054991910f39c smoocave_en-au10358472670_1366x768.jpg
dc3ad6658d8f8155c74054991910f39c smoocave_en-au10358472670_1366x7682.jpg

Как я могу обработать основанный на MD5 файл для удаления дубликатов? Мне все равно, какой «оригинал» я храню, но я хочу сохранить только один

Должен ли я подходить к этому по-другому?


3
Уже есть fdupesкоманда, которая сделает это ... Не знаю, в каком дистрибутиве вы находитесь, но в пакете Debian с тем же именем. Кроме того, MD5 в настоящее время является довольно слабым хэшем; Вы, вероятно, хотите использовать sha256sum или лучше sha512sum(что на самом деле должно быть быстрее на обычном ПК)
derobert

1
@derobert - я знаю, что MD5 - слабый хеш, но он прост и достаточно хорош для сравнения небольших файлов :)
Уоррен

ну, коллизии MD5 известны и генерируются с довольно скромными объемами мощности процессора, и есть команда, которую вы можете заменить, чтобы использовать вместо
нее

@derobert - я понимаю, что есть потенциальные недостатки использования md5 .. но в этом сценарии его более чем достаточно (чтобы убедиться, что у меня нет дубликатов файлов в данном каталоге)
warren

1
Справедливо. Главным пунктом комментария было указать на fdupes.
Дероберт

Ответы:


3

Я работаю над Linux, что означает команду, md5sumкоторая выводит:

> md5sum *
d41d8cd98f00b204e9800998ecf8427e  file_1
d41d8cd98f00b204e9800998ecf8427e  file_10
d41d8cd98f00b204e9800998ecf8427e  file_2
d41d8cd98f00b204e9800998ecf8427e  file_3
d41d8cd98f00b204e9800998ecf8427e  file_4
d41d8cd98f00b204e9800998ecf8427e  file_5
d41d8cd98f00b204e9800998ecf8427e  file_6
d41d8cd98f00b204e9800998ecf8427e  file_7
d41d8cd98f00b204e9800998ecf8427e  file_8
d41d8cd98f00b204e9800998ecf8427e  file_9
b026324c6904b2a9cb4b88d6d61c81d1  other_file_1
31d30eea8d0968d6458e0ad0027c9f80  other_file_10
26ab0db90d72e28ad0ba1e22ee510510  other_file_2
6d7fce9fee471194aa8b5b6e47267f03  other_file_3
48a24b70a0b376535542b996af517398  other_file_4
1dcca23355272056f04fe8bf20edfce0  other_file_5
9ae0ea9e3c9c6e1b9b6252c8395efdc1  other_file_6
84bc3da1b3e33a18e8d5e1bdd7a18d7a  other_file_7
c30f7472766d25af1dc80b3ffc9a58c7  other_file_8
7c5aba41f53293b712fd86d08ed5b36e  other_file_9

Теперь с помощью awkи xargsкоманда будет:

md5sum * | \
sort | \
awk 'BEGIN{lasthash = ""} $1 == lasthash {print $2} {lasthash = $1}' | \
xargs rm

В awkчасти инициализирует lasthashс пустой строки, которые не будут соответствовать какой - либо хэш, а затем проверяет каждую строку , если хэш в lasthashтакой же , как хэш (первый столбец) текущего файла (второй столбец). Если это так, он распечатывает это. В конце каждого шага он будет установлен lasthashна хеш текущего файла (вы можете ограничить его, если он будет отличаться, только если хэши разные, но это должно быть второстепенным, особенно если у вас мало подходящих файлов). Имена файлов, которыми выплевывает awk, передаются с rmпомощью xargs, что в основном вызывает rmто, что awkнам дает часть.

Вы, вероятно, должны фильтровать каталоги раньше md5sum *.

Редактировать:

Используя метод Marcins, вы также можете использовать этот:

comm -1 -2 \
  <(ls) | \
  <(md5sum * | \
    sort -k1 | \
    uniq -w 32 | \
    awk '{print $2}' | \
    sort) \
xargs rm

Это вычитание из списка файлов, открытого lsпервым именем файла каждого уникального хэша, выбранного md5sum * | sort -k1 | uniq -w 32 | awk '{print $2}'.


1
спасибо: md5 -r * | sort -t ' ' -k 4 -r | awk 'BEGIN{lasthash = ""} $1 == lasthash {print $2} {lasthash = $1}' | xargs rmэто вызов на OS X (по предложению Стивена Китта , я ставлю echo 'will remove 'в конце, прежде чем пытаться это сделать rm)
Уоррен

Вы, вероятно, должны отредактировать свой вопрос тогда, потому что данное решение не совпадает с выходным примером, который вы дали.
Стивен Китт

1
И вы должны измениться sort -t ' ' -k 4 -rна sort.
Тристан Шторх

@TristanStorch - хорошее место :)
Уоррен

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

7

Вы можете идентифицировать дубликаты файлов, используя следующую команду:

md5sum * | sort -k1 | uniq -w 32 -d

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

2

Я наткнулся на fdupes как ответ на этот похожий вопрос: /superuser/386199/how-to-remove-duplicated-files-in-a-directory

Я был в состоянии apt-get install fdupesна Ubuntu. Вы определенно захотите прочитать справочную страницу. В моем случае я смог получить желаемые результаты примерно так:

fdupes -qdN -r /ops/backup/

Который говорит: «Посмотрите рекурсивно через / ops / backup и найдите все дубликаты файлов: сохраните первую копию любого данного файла и спокойно удалите остальные». Это позволяет легко сохранять несколько дампов базы данных с нечастой записью.


1

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

find . -type f -print0 | xargs -0 md5sum | awk 'h[$1]{ printf "%s\0", $2; next }{ h[$1] = $2 }' | xargs -0 rm

find . -type f -print0: Найти все файлы и вывести их с именами, заканчивающимися на ноль

xargs -0 md5sum: вычислять хэши параллельно (отрегулировать -nmax-args и -Pmax-procs по желанию, см. man xargs)

awk 'h[$1]{ printf "%s\0", $2; next }{ h[$1] = $2 }': если в хеш-таблице awk есть запись, содержащая сумму md5, которую мы сейчас просматриваем, то выведите имя файла, который мы сейчас просматриваем, с нулевым символом в конце. В противном случае добавьте имя файла в хеш-таблицу.

xargs -0 rm: возьмите введенные строки с нулевым окончанием и отправьте их в rm.

Это намного быстрее, чем fdupes.

Если у вас есть имя файла, которое содержит символ новой строки, awk, вероятно, обрежет его до новой строки, так как md5sum также разделяет записи по символам новой строки.

Это основано на /programming/11532157/remove-duplicate-lines-without-sorting и /programming/9133315/how-can-i-output-null-terminated- строки-в-AWK


1
md5sum * | sort -k1 | uniq -w 32 -d | cut -d' ' -f3 | xargs -I{} sh -c 'rm {}'
  1. принять все значения md5
  2. сортировать их так, чтобы дуплеты были последовательны для уникальности
  3. запустить uniq только для вывода дупов
  4. вырезать имя файла из строки со значением md5
  5. неоднократно вызывать удаление по именам файлов

0
comm -13 <(md5sum * | sort | uniq -w 32 -d) <(md5sum * | sort | uniq -w 32 -D) | cut -f 3- -d" " | xargs -d '\n' rm

Особенности:

  • По-прежнему работает, если в файле несколько дубликатов
  • По-прежнему работает, если в именах файлов есть пробелы
  • По-прежнему работает, если у вас есть псевдоним lsс--color=always
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.