Чтобы найти дубликаты файлов в Linux из командной строки без установки пакетов, посчитайте md5-сумму каждого файла и оставьте только совпадения через uniq: find d -type f -exec md5sum {} + | sort | uniq -w32 -dD. Весь топ поисковой выдачи — обзоры утилит, которые сначала нужно поставить: fdupes, rdfind, rmlint. На чужом сервере или в контейнере ставить пакеты часто негде и некогда. Ниже — конвейер из того, что уже есть в системе, и честная граница, где утилиту всё же стоит поставить.
1. Дубликаты по содержимому, без установки пакетов
$ clai найди файлы с одинаковым содержимым в папке d→ find d -type f -exec md5sum {} + | sort | uniq -w32 -dD4f784201526479699db75d69c7abad6d d/a/one.txt4f784201526479699db75d69c7abad6d d/b/two-copy.txt
uniq -w32 сравнивает только первые 32 символа строки — это ровно длина md5-суммы, то есть сравнение идёт по хешу, а не по имени. -d оставляет только повторы, -D печатает все строки группы, а не одну.
2. Сначала посчитать, потом решать
$ clai сколько всего групп дубликатов→ find d -type f -exec md5sum {} + | sort | uniq -w32 -d | wc -l
Одна строка на группу. Если групп три — разберётесь глазами. Если три тысячи — нужна утилита с интерактивным режимом, а не конвейер.
3. Не хешировать терабайты зря
$ clai найди дубликаты только среди файлов больше 10 мегабайт→ find . -type f -size +10M -exec md5sum {} + | sort | uniq -w32 -dD
md5 читает файл целиком. На большом дереве отбор по размеру ускоряет всё на порядок, а место занимают именно крупные файлы.
4. Быстрее: сначала по размеру, потом по хешу
$ clai найди дубликаты быстро, сначала отсеяв по размеру→ find . -type f -printf '%s\n' | sort -n | uniq -d | while read s; do find . -type f -size "${s}c" -exec md5sum {} + ; done | sort | uniq -w32 -dD
Файлы разного размера дубликатами быть не могут. Хешируются только те, у кого совпал размер. На дереве с миллионом файлов это разница между минутами и часами.
5. Оставить по одному файлу из каждой группы
$ clai покажи какие дубликаты можно удалить, оставив по одной копии→ find . -type f -exec md5sum {} + | sort | uniq -w32 -d --all-repeated=separate | awk 'seen[$1]++ {print $2}'
awk 'seen[$1]++' пропускает первое вхождение хеша и печатает все последующие — то есть список кандидатов на удаление. Это список для чтения, а не для | xargs rm. Прочитайте его.
6. Когда всё-таки ставить утилиту
$ clai найди дубликаты и предложи удалить интерактивно→ fdupes -r -d .
Если групп сотни и нужен диалог по каждой, fdupes -d спрашивает, что оставить. rdfind умеет заменять дубликаты жёсткими ссылками, не удаляя ничего. Конвейер выше нужен там, где ставить пакеты нельзя.
Грабли
- md5 достаточно для дубликатов, но не для безопасности. Коллизию md5 можно построить намеренно, случайно она не встретится. Для проверки целостности берите sha256, для поиска копий md5 быстрее и хватает.
- Жёсткие ссылки выглядят как дубликаты. Один и тот же файл под двумя именами даст одинаковый хеш, но места занимает один раз. Отсекайте по номеру инода:
find . -type f -printf '%i %p\n' | sort -u -k1,1. - Никогда не подавайте список сразу в rm. Один неверный фильтр — и вы удалите обе копии. Сохраните список в файл, прочитайте, потом удаляйте.
Похожие вопросы
Как найти дубликаты по имени, а не по содержимому? find . -type f -printf '%f\n' | sort | uniq -d покажет повторяющиеся имена в разных каталогах.
Работает ли это на macOS? Замените md5sum на md5 -r — формат вывода совпадёт. -printf в find придётся заменить на -exec stat -f.
Что быстрее для сотен тысяч файлов? Вариант из четвёртой секции или rdfind, который сортирует по инодам перед чтением диска.
Читайте также
- Какая папка ест место на диске? du, отсортированный по размеру
- df говорит, что диск полон, du — что нет
- Хватит запоминать флаги find
CliAI не посчитает хеш за вас, но избавит от подбора флага uniq -w32 каждый раз заново. Установите одной строкой.