Linux #Linux #Ubuntu #Терминал #find #grep #Шпаргалка

Как найти файл в Linux: find, locate, fd и grep

Как найти файл в Linux по имени, размеру, дате и правам через find, мгновенно — через locate, удобно — через fd, а по содержимому — grep и ripgrep. Плюс which, dpkg -S и готовые рецепты с реальным выводом.

46 минут 1
Содержание
  1. 1Тестовая папка
  2. 2find — главный инструмент
  3. По имени: -name и -iname
  4. По типу: -type
  5. Ограничить глубину: -maxdepth
  6. По размеру: -size
  7. По дате изменения: -mtime, -mmin, -newer
  8. По правам и владельцу: -perm, -user, -group
  9. Исключить папку: -prune
  10. Поиск по всей системе и ошибки «Permission denied»
  11. 3Действия с найденным: -exec, -delete и xargs
  12. -exec — выполнить команду для каждого файла
  13. -delete — удалить найденное
  14. xargs -0 — передать файлы другой команде
  15. 4locate — мгновенный поиск по имени
  16. Почему locate не находит новый файл
  17. 5fd — удобная замена find
  18. 6Поиск по содержимому: grep
  19. 7ripgrep (rg) — быстрый grep для проектов
  20. 8Где программа и из какого она пакета
  21. which, type, command -v
  22. whereis
  23. dpkg -S — какой пакет установил файл
  24. apt-file — в каком пакете файл, который ещё не установлен
  25. 9Готовые рецепты
  26. Найти самые большие файлы
  27. Найти файлы, изменённые сегодня
  28. Найти и удалить пустые папки
  29. Удалить старые логи
  30. Найти дубликаты по MD5
  31. 10Шпаргалка: задача → команда
  32. 11Частые ошибки
  33. 12Чек-лист
  34. 13Частые вопросы
  35. Чем find отличается от locate?
  36. Как найти файл по части имени?
  37. Как найти файл по всему компьютеру?
  38. Почему в Ubuntu нет команды fd?
  39. Как найти файл, в котором есть определённый текст?
  40. Как найти и удалить файлы старше N дней?
  41. Как узнать, где установлена программа?
  42. Чем grep отличается от ripgrep?

В графическом файловом менеджере поиск есть, но он медленный и умеет мало: найти файл по части имени — пожалуйста, а вот «все фото больше 10 МБ, изменённые за последний месяц, кроме папки с бэкапами» — уже нет. На сервере без рабочего стола и вовсе остаётся только терминал.

В Linux для поиска есть четыре главных инструмента. find ищет по любым признакам файла и есть везде. locate находит файл по имени мгновенно, потому что ищет по заранее собранной базе. fd — современная и более удобная замена find. А grep и ripgrep ищут не по имени, а по тексту внутри файлов.

Все примеры ниже я запускал в Ubuntu 24.04 на тестовой папке ~/demo-проект: в ней есть исходники, логи, фотографии, бэкап и пара пустых каталогов. Выводы настоящие, только пути показаны для пользователя nixlife.

Тестовая папка

Чтобы примеры было с чем сравнивать, вот содержимое папки, по которой будем искать:

Терминал
cd ~/demo-проект
find . | sort
Вывод
.
./README.md
./backup
./backup/notes-copy.txt
./backup/site-backup.tar.gz
./deploy.sh
./docs
./docs/notes.txt
./docs/old
./docs/old/plan-2025.txt
./docs/Отчёт.docx
./empty
./empty/sub
./logs
./logs/app-01.log
./logs/app-02.log
./logs/app-03.log
./logs/app.log
./node_modules
./node_modules/lodash
./node_modules/lodash/index.js
./photos
./photos/IMG_0001-копия.JPG
./photos/IMG_0001.JPG
./photos/img_0002.jpg
./photos/vacation.png
./src
./src/db.php
./src/index.php
./src/utils
./src/utils/config.js
./src/utils/parser.py
./tmp
./tmp/cache.tmp
./tmp/session.tmp

find без условий просто выводит всё дерево — уже полезно, когда нужно быстро понять, что лежит в незнакомой папке.

find — главный инструмент

find есть в любом дистрибутиве из коробки (пакет findutils). Общая схема команды:

Терминал
find ГДЕ_ИСКАТЬ УСЛОВИЯ ДЕЙСТВИЕ
  • Где искать — одна или несколько папок: . — текущая, ~ — домашняя, / — вся система.
  • Условия — имя, тип, размер, дата, права. Несколько условий объединяются через «И».
  • Действие — что сделать с найденным. По умолчанию это -print, то есть просто вывести путь.

По имени: -name и -iname

-name ищет по имени файла с учётом регистра. Звёздочка * заменяет любые символы, поэтому шаблон обязательно берите в кавычки — иначе оболочка раскроет звёздочку раньше, чем find её увидит.

Терминал
find . -name "*.jpg"
Вывод
./photos/img_0002.jpg

Нашёлся только один файл, хотя фотографий три: у двух других расширение написано заглавными буквами — .JPG. Для поиска без учёта регистра есть -iname:

Терминал
find . -iname "*.jpg"
Вывод
./photos/IMG_0001-копия.JPG
./photos/img_0002.jpg
./photos/IMG_0001.JPG

Если указать полный путь к папке, find и в выводе покажет полные пути — это удобно, когда результат нужно куда-то скопировать:

Терминал
find ~/demo-проект -name "*.php"
Вывод
/home/nixlife/demo-проект/src/index.php
/home/nixlife/demo-проект/src/db.php

Кириллица в именах работает так же: find . -iname "*копия*" найдёт ./photos/IMG_0001-копия.JPG.

По типу: -type

  • -type f — обычные файлы;
  • -type d — каталоги;
  • -type l — символические ссылки.
Терминал
find . -type d -name "old"
Вывод
./docs/old

Тип стоит указывать почти всегда: так вы не получите в результатах папку, которая случайно называется как искомый файл.

Ограничить глубину: -maxdepth

По умолчанию find спускается во все вложенные папки. Чтобы искать только в текущей, добавьте -maxdepth 1:

Терминал
find . -maxdepth 1 -type f
Вывод
./README.md
./deploy.sh

По размеру: -size

Суффиксы: c — байты, k — килобайты, M — мегабайты, G — гигабайты. Плюс означает «больше», минус — «меньше».

Терминал
find . -type f -size +10M
Вывод
./backup/site-backup.tar.gz
./photos/IMG_0001-копия.JPG
./photos/IMG_0001.JPG

Чтобы сразу увидеть размеры, добавьте действие -exec ls -lh (о -exec подробнее ниже):

Терминал
find . -type f -size +10M -exec ls -lh {} \;
Вывод
-rw-rw-r-- 1 nixlife nixlife 50M Jun  1 00:00 ./backup/site-backup.tar.gz
-rw-rw-r-- 1 nixlife nixlife 12M Sep  1 00:00 ./photos/IMG_0001-копия.JPG
-rw-rw-r-- 1 nixlife nixlife 12M Sep  1 00:00 ./photos/IMG_0001.JPG

По дате изменения: -mtime, -mmin, -newer

  • -mtime -1 — изменённые меньше суток назад;
  • -mtime +30 — изменённые больше 30 суток назад (дробные сутки отбрасываются, поэтому фактически от 31 дня);
  • -mmin -60 — то же в минутах: за последний час.
Терминал
find . -type f -mtime +30
Вывод
./backup/site-backup.tar.gz
./docs/Отчёт.docx
./docs/old/plan-2025.txt
./photos/IMG_0001-копия.JPG
./photos/img_0002.jpg
./photos/IMG_0001.JPG
./photos/vacation.png

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

Терминал
find . -newer README.md -type f

Для конкретных дат есть -newermt. Найдём файлы, изменённые в сентябре 2026 года:

Терминал
find . -type f -newermt "2026-08-31" ! -newermt "2026-10-01"
Вывод
./docs/Отчёт.docx
./photos/IMG_0001-копия.JPG
./photos/img_0002.jpg
./photos/IMG_0001.JPG
./photos/vacation.png

Восклицательный знак ! — это отрицание: «новее 31 августа и не новее 1 октября». Учтите, что «новее» понимается строго: файл, изменённый ровно в полночь 1 сентября, условию -newermt "2026-09-01" уже не соответствует, поэтому нижнюю границу я взял с запасом.

-ctime и -atime работают так же, но смотрят на время изменения метаданных и последнего чтения. В повседневных задачах почти всегда нужен -mtime.

По правам и владельцу: -perm, -user, -group

-perm бывает трёх видов:

  • -perm 644 — права совпадают точно;
  • -perm -u=x — установлены все перечисленные биты (здесь — файл исполняемый для владельца);
  • -perm /o=w — установлен хотя бы один бит (здесь — запись разрешена всем).

Поиск файлов, которые может изменить кто угодно, — частая проверка на сервере:

Терминал
find . -type f -perm /o=w
Вывод
./src/utils/config.js

Владельца ищут через -user и -group, а файлы «без хозяина» (пользователя удалили, а файлы остались) — через -nouser:

Терминал
find . -user nixlife -name "*.sh"
Вывод
./deploy.sh

Если запись o=w или -u=x пока непривычна, поможет калькулятор chmod: он переводит буквенные права в числовые и обратно.

Исключить папку: -prune

Папки вроде node_modules, .git или vendor часто содержат тысячи файлов и только мешают. Классический способ пропустить их — -prune:

Терминал
find . -path ./node_modules -prune -o -name "*.js" -print
Вывод
./src/utils/config.js

Читается так: «если путь — ./node_modules, не заходи внутрь; иначе (-o) ищи *.js и выводи». -print в конце обязателен — без него find выведет и саму пропущенную папку.

Вариант попроще для запоминания:

Терминал
find . -name "*.js" -not -path "*/node_modules/*"

Результат тот же, но есть разница: -not -path всё равно обходит всю папку и только отбрасывает её файлы из вывода, а -prune вообще туда не заходит. На больших деревьях -prune заметно быстрее.

Поиск по всей системе и ошибки «Permission denied»

Если искать от корня обычным пользователем, вывод утонет в сообщениях об отказе в доступе:

Терминал
find / -name fstab
Вывод
find: ‘/etc/redis’: Permission denied
find: ‘/etc/credstore.encrypted’: Permission denied
find: ‘/etc/polkit-1/rules.d’: Permission denied
find: ‘/etc/credstore’: Permission denied
…

Сообщения об ошибках идут в отдельный поток, и их можно выбросить, добавив 2>/dev/null. Ключ -xdev заодно не даёт find уходить на другие файловые системы — сетевые папки, флешки, /proc:

Терминал
find / -xdev -name fstab 2>/dev/null
Вывод
/etc/fstab

Если нужно найти и то, что закрыто для вашего пользователя, запускайте через sudo — подробнее о правах суперпользователя в статье про root в Ubuntu.

Действия с найденным: -exec, -delete и xargs

-exec — выполнить команду для каждого файла

{} подставляет путь к найденному файлу, а окончание команды задаётся одним из двух способов:

  • \; — команда запускается отдельно для каждого файла;
  • + — найденные файлы передаются пачкой в один запуск. Это быстрее.

Найдём логи, в которых есть ошибки:

Терминал
find . -name "*.log" -exec grep -l ERROR {} +
Вывод
./logs/app-01.log
./logs/app-02.log
./logs/app-03.log

Если хочется подтверждать каждое действие, вместо -exec используйте -ok — find спросит перед каждым файлом:

Пример вывода
< rm ... ./logs/app-01.log > ? y
< rm ... ./logs/app-02.log > ? n

-delete — удалить найденное

Терминал
find . -name "*.tmp" -delete -print
Вывод
./tmp/session.tmp
./tmp/cache.tmp

-print после -delete здесь только для того, чтобы увидеть, что именно удалено.

xargs -0 — передать файлы другой команде

xargs берёт список путей и подставляет их в аргументы команды. Но у простой связки find | xargs есть проблема — пробелы в именах. Добавим в логи файл my file.log и посмотрим:

Терминал
find . -name "*.log" | xargs ls -1
Вывод
ls: cannot access './logs/my': No such file or directory
ls: cannot access 'file.log': No such file or directory
./logs/app-01.log
./logs/app-02.log
./logs/app-03.log
./logs/app.log

xargs разрезал имя по пробелу на два несуществующих файла. Решение — разделять имена нулевым байтом, который не может встретиться в имени файла: -print0 у find и -0 у xargs:

Терминал
find . -name "*.log" -print0 | xargs -0 ls -1
Вывод
./logs/app-01.log
./logs/app-02.log
./logs/app-03.log
./logs/app.log
./logs/my file.log

Используйте пару -print0 | xargs -0 всегда, даже если уверены, что пробелов в именах нет. Файлы с именами вроде Отчёт за сентябрь.docx рано или поздно появятся.

locate — мгновенный поиск по имени

find каждый раз обходит диск заново, и на большом сервере поиск от корня может занять минуты. locate работает иначе: ищет по базе имён файлов, которую раз в сутки обновляет служба updatedb. Поэтому ответ приходит за доли секунды.

В Ubuntu 24.04 locate — это программа plocate. Если команды нет, установите её:

Терминал
sudo apt install plocate

Ищется любая часть пути, ключ -i отключает учёт регистра:

Терминал
locate -i отчёт
Вывод
/home/nixlife/demo-проект/docs/Отчёт.docx

Полезные ключи:

  • -c — только посчитать совпадения: locate -c "*.jpg";
  • -l 10 — вывести не больше 10 результатов;
  • -b — искать только в имени файла, а не во всём пути;
  • -r — регулярное выражение. Например, точное имя файла: locate -r '/fstab$'.

Почему locate не находит новый файл

Главный минус — база устаревает. Создадим файл и сразу поищем:

Терминал
touch ~/demo-проект/docs/new-idea.md
locate new-idea
echo $?
Вывод
1

Ничего не нашлось, код возврата 1. Файл появился после последнего обновления базы. Обновим её вручную — это требует прав root:

Терминал
sudo updatedb
locate new-idea
Вывод
/home/nixlife/demo-проект/docs/new-idea.md

Автоматически база обновляется таймером plocate-updatedb.timer раз в сутки. Какие папки и файловые системы updatedb пропускает (например, /tmp, сетевые NFS и SMB), записано в /etc/updatedb.conf. Поэтому файлы на подключённой сетевой папке Samba через locate обычно не найти.

fd — удобная замена find

fd делает то же, что find, но с более короткими командами, цветным выводом и разумными умолчаниями: он не показывает скрытые файлы и пропускает то, что перечислено в .gitignore.

Терминал
sudo apt install fd-find

В Ubuntu и Debian команда называется fdfind: имя fd уже было занято другим пакетом. Чтобы писать коротко, добавьте псевдоним в ~/.bashrc:

Терминал
echo "alias fd=fdfind" >> ~/.bashrc
source ~/.bashrc

Дальше в примерах я пишу fdfind, чтобы команды работали и без псевдонима.

Самый простой поиск — часть имени, без звёздочек и кавычек. Регистр fd по умолчанию игнорирует, если в запросе только строчные буквы:

Терминал
fdfind jpg
Вывод
photos/IMG_0001-копия.JPG
photos/IMG_0001.JPG
photos/img_0002.jpg

Для дальнейших примеров считаем, что ~/demo-проект — git-репозиторий, а в .gitignore записана папка node_modules/. Тогда fd её просто не видит:

Терминал
fdfind -e js
Вывод
src/utils/config.js
Терминал
fdfind -I -e js
Вывод
node_modules/lodash/index.js
src/utils/config.js

Основные ключи:

  • -e js — по расширению;
  • -t f / -t d — только файлы или только каталоги;
  • -H — включить скрытые файлы, -I — не учитывать .gitignore;
  • -E docs — исключить папку;
  • -g "*.php" — шаблон как в find, вместо регулярного выражения;
  • -S +10M — по размеру;
  • --changed-within 1d — изменённые за последние сутки;
  • -x команда — выполнить для каждого файла, -X команда — для всех разом.
Терминал
fdfind -t f -S +10M
Вывод
backup/site-backup.tar.gz
photos/IMG_0001-копия.JPG
photos/IMG_0001.JPG

Запрос по умолчанию — регулярное выражение, поэтому можно искать точнее:

Терминал
fdfind '^app-\d+\.log$'
Вывод
logs/app-01.log
logs/app-02.log
logs/app-03.log

-X передаёт файлам пробелы безопасно, никакой -print0 не нужен:

Терминал
fdfind -e log -X wc -l
Вывод
  1 ./logs/app.log
  1 ./logs/my file.log
  1 ./logs/app-03.log
  1 ./logs/app-02.log
  1 ./logs/app-01.log
  5 total

Чтобы искать в другой папке, укажите её вторым аргументом, а первым — шаблон. Точка означает «всё»: fdfind . ~/demo-проект/src -t f.

Поиск по содержимому: grep

Когда имя файла неизвестно, но вы помните, что внутри, нужен grep. С ключом -r он обходит папку рекурсивно, а -n показывает номер строки:

Терминал
grep -rn TODO .
Вывод
./src/index.php:1:<?php echo 'Hello'; // TODO: убрать
./src/db.php:3:  // TODO: вынести пароль в .env
./README.md:2:TODO: написать README
./backup/notes-copy.txt:2:TODO купить диски
./docs/notes.txt:2:TODO купить диски

Формат строки — файл:номер_строки:текст. Самые нужные ключи:

  • -i — без учёта регистра. grep -rni todo . найдёт ещё и # todo: обработать ошибки в parser.py;
  • -l — только имена файлов, без строк. Удобно, когда совпадений сотни;
  • -c — сколько совпадений в каждом файле;
  • -w — только целое слово;
  • --include="*.php" — искать только в файлах по шаблону;
  • --exclude-dir=node_modules — пропустить папку;
  • -A 2, -B 2, -C 2 — показать 2 строки после, до или вокруг совпадения;
  • -E — расширенные регулярные выражения: grep -rE "ERROR|WARN" logs.

Разница с -w хорошо видна на переменных:

Терминал
grep -rn pass src
Вывод
src/db.php:4:  $pass = getenv('DB_PASS');
src/db.php:5:  $password_hash = '';
Терминал
grep -rnw pass src
Вывод
src/db.php:4:  $pass = getenv('DB_PASS');

С -w строка с password_hash отпала: там pass — только часть слова.

Ограничиваем поиск типом файлов:

Терминал
grep -rn --include="*.php" TODO .
Вывод
./src/index.php:1:<?php echo 'Hello'; // TODO: убрать
./src/db.php:3:  // TODO: вынести пароль в .env

Посчитать ошибки в логах:

Терминал
grep -rc ERROR logs
Вывод
logs/app-01.log:1
logs/app-02.log:1
logs/app-03.log:1
logs/app.log:0

ripgrep (rg) — быстрый grep для проектов

ripgrep — это grep -rn с умными умолчаниями: ищет рекурсивно сразу, показывает номера строк, пропускает скрытые и двоичные файлы, а также всё из .gitignore. На больших проектах он заметно быстрее.

Терминал
sudo apt install ripgrep
Терминал
rg -i todo
Вывод
docs/notes.txt
2:TODO купить диски

backup/notes-copy.txt
2:TODO купить диски

README.md
2:TODO: написать README

src/utils/parser.py
2:    # todo: обработать ошибки

src/db.php
3:  // TODO: вынести пароль в .env

src/index.php
1:<?php echo 'Hello'; // TODO: убрать

В терминале rg группирует совпадения по файлам: сначала имя файла, под ним — номер строки и текст. Если вывод идёт в файл или в конвейер, формат становится как у grep — файл:текст, а номера строк нужно запросить ключом -n. Порядок файлов может отличаться от запуска к запуску: rg ищет в несколько потоков.

Полезные ключи:

  • -t php — только файлы указанного типа (список типов — rg --type-list);
  • -g "!*.txt" — исключить файлы по шаблону;
  • -l, -c, -w, -i — как у grep;
  • --no-ignore — не учитывать .gitignore, -uu — заодно искать в скрытых файлах.

Как и fd, rg не заглядывает в node_modules из .gitignore:

Терминал
rg exports
rg --no-ignore exports
Вывод
node_modules/lodash/index.js
1:module.exports = {}

Первая команда ничего не нашла, вторая — нашла.

Где программа и из какого она пакета

Отдельная задача — найти не документ, а команду: где лежит исполняемый файл, какой пакет его установил, в каком пакете искать недостающую программу.

which, type, command -v

which показывает, какой файл запустится по имени команды:

Терминал
which python3
Вывод
/usr/bin/python3

Но which ничего не знает о псевдонимах и встроенных командах оболочки. Честный ответ даёт type:

Терминал
type ls
type cd
type ll
Вывод
ls is aliased to `ls --color=auto'
cd is a shell builtin
ll is aliased to `ls -alF'

command -v выводит путь, а если программы нет — ничего и возвращает ошибку. Поэтому именно его используют в скриптах для проверки, установлена ли программа:

Терминал
command -v fdfind || echo "не установлено"
Вывод
/usr/bin/fdfind

whereis

whereis находит сразу исполняемый файл, исходники и документацию. С ключом -b — только исполняемый файл:

Терминал
whereis -b find
Вывод
find: /usr/bin/find

dpkg -S — какой пакет установил файл

Терминал
dpkg -S /usr/bin/find
Вывод
findutils: /usr/bin/find

Иногда dpkg -S отвечает, что ничего не нашёл, хотя файл точно есть:

Терминал
dpkg -S /usr/bin/locate
Вывод
dpkg-query: no path found matching pattern /usr/bin/locate

Дело в том, что /usr/bin/locate — символическая ссылка через систему альтернатив, а не файл пакета. Сначала узнайте настоящий путь через readlink -f:

Терминал
dpkg -S "$(readlink -f /usr/bin/locate)"
Вывод
plocate: /usr/bin/plocate

Обратная задача — какие файлы поставил пакет — решается через dpkg -L:

Терминал
dpkg -L fd-find | grep bin
Вывод
/usr/bin
/usr/lib/cargo/bin
/usr/lib/cargo/bin/fd
/usr/bin/fdfind

apt-file — в каком пакете файл, который ещё не установлен

dpkg -S знает только про установленные пакеты. Чтобы понять, какой пакет поставить ради нужной команды, есть apt-file. Перед первым использованием ему нужно скачать индекс:

Терминал
sudo apt install apt-file
sudo apt-file update
apt-file search bin/rg
Вывод (сокращён)
gdal-bin: /usr/bin/rgb2pct.py
grep: /usr/bin/rgrep
…
ripgrep: /usr/bin/rg

Поиск идёт по подстроке, поэтому совпадений много. Точнее — регулярным выражением: apt-file search --regexp '/rg$' выдаст только ripgrep: /usr/bin/rg. Подробнее про установку программ разными способами — в статье apt, snap, flatpak и AppImage.

Готовые рецепты

Найти самые большие файлы

Терминал
find . -type f -size +1M -exec du -h {} + | sort -rh | head -5
Вывод
50M    ./backup/site-backup.tar.gz
12M    ./photos/IMG_0001.JPG
12M    ./photos/IMG_0001-копия.JPG
3.0M    ./photos/img_0002.jpg
2.0M    ./photos/vacation.png

du -h выводит размер в удобных единицах, sort -rh сортирует такие размеры по убыванию, head -5 оставляет пять первых. Для поиска по всему диску замените . на /, добавьте -xdev, sudo и 2>/dev/null. Как разобраться, чем вообще занято место, — в статье место на диске в Linux.

Найти файлы, изменённые сегодня

-mtime -1 считает последние 24 часа, а не календарный день. Для «с начала сегодняшнего дня» есть -daystart:

Терминал
find . -type f -daystart -mtime 0

Найти и удалить пустые папки

Терминал
find . -type d -empty
Вывод
./empty/sub

./empty в список не попала: внутри неё есть sub. Но если сразу добавить -delete, find удаляет вложенные папки раньше родительских, и опустевшие родители тоже уйдут:

Терминал
find . -type d -empty -delete -print
Вывод
./tmp
./empty/sub
./empty

Удалилась и ./tmp — она опустела ещё раньше, когда мы стёрли из неё .tmp-файлы.

Удалить старые логи

Логи старше 30 дней — типичная задача для расписания. Сначала проверьте список, потом удаляйте:

Терминал
find /var/log/myapp -name "*.log" -mtime +30
find /var/log/myapp -name "*.log" -mtime +30 -delete

Чтобы это происходило само, добавьте вторую команду в cron — собрать расписание поможет генератор cron.

Найти дубликаты по MD5

Простой конвейер без установки дополнительных программ:

Терминал
find . -type f -exec md5sum {} + | sort | uniq -w32 -D
Вывод
91c65b668fcca2994f02ca5bef556e8c  ./backup/notes-copy.txt
91c65b668fcca2994f02ca5bef556e8c  ./docs/notes.txt
d41d8cd98f00b204e9800998ecf8427e  ./tmp/cache.tmp
d41d8cd98f00b204e9800998ecf8427e  ./tmp/session.tmp
d6cf19fa5373d4f8c985d2989775ac3b  ./photos/IMG_0001-копия.JPG
d6cf19fa5373d4f8c985d2989775ac3b  ./photos/IMG_0001.JPG

Как это работает: md5sum считает контрольную сумму каждого файла, sort ставит одинаковые суммы рядом, а uniq -w32 -D сравнивает только первые 32 символа (саму сумму) и выводит все повторяющиеся строки. Пустые файлы тоже попадают в «дубликаты» — у них одинаковая сумма d41d8cd9….

Хеширование гигабайтов фото и видео идёт долго, поэтому на больших папках сначала отсейте мелочь, а группы разделите пустой строкой:

Терминал
find . -type f -size +1M -exec md5sum {} + | sort | uniq -w32 --all-repeated=separate
Вывод
d6cf19fa5373d4f8c985d2989775ac3b  ./photos/IMG_0001-копия.JPG
d6cf19fa5373d4f8c985d2989775ac3b  ./photos/IMG_0001.JPG

Шпаргалка: задача → команда

ЗадачаКоманда
Файл по имени без учёта регистраfind . -iname "*отчёт*"
Только в текущей папкеfind . -maxdepth 1 -type f
Мгновенно по всей системеlocate -i имя
Обновить базу locatesudo updatedb
Файлы больше 100 МБfind / -xdev -type f -size +100M 2>/dev/null
Изменённые за суткиfind . -type f -mtime -1
Изменённые за последний часfind . -type f -mmin -60
Не менявшиеся больше месяцаfind . -type f -mtime +30
Доступные на запись всемfind . -type f -perm /o=w
Файлы пользователяfind / -user nixlife 2>/dev/null
Без папки node_modulesfind . -path ./node_modules -prune -o -name "*.js" -print
Пустые файлы и папкиfind . -empty
Удалить найденноеfind . -name "*.tmp" -delete
Передать файлы с пробеламиfind . -print0 | xargs -0 команда
Удобный поиск по имениfdfind имя, fdfind -e jpg
Текст внутри файловgrep -rn "текст" .
Только имена файлов с текстомgrep -rl "текст" .
Текст только в PHP-файлахgrep -rn --include="*.php" "текст" .
Быстро по проектуrg "текст", rg -t php "текст"
Где лежит программаcommand -v имя, type имя
Из какого пакета файлdpkg -S /путь/к/файлу
В каком пакете команда (не установлена)apt-file search bin/имя
Дубликаты файловfind . -type f -exec md5sum {} + | sort | uniq -w32 -D

Частые ошибки

  • 🔤 Шаблон без кавычек. Если в текущей папке лежат a.jpg и b.jpg, команда find . -name *.jpg превратится в find . -name a.jpg b.jpg ещё до запуска, и find ответит ошибкой paths must precede expression: 'b.jpg'. А если такой файл один, поиск молча пойдёт только по его имени. Берите шаблоны в кавычки.
  • 🔠 Регистр. -name "*.jpg" не найдёт IMG_0001.JPG. Если не уверены, пишите -iname.
  • 📏 -size -1M находит только пустые файлы — из-за округления вверх. Для маленьких размеров используйте байты: -size -1048576c.
  • 🗑️ -delete не в конце. Условия проверяются слева направо, и -delete в начале удалит всё подряд.
  • 🕒 locate не видит новый файл. База обновляется раз в сутки, запустите sudo updatedb.
  • 🙈 fd и rg «не находят» файл. Скорее всего, он скрытый или указан в .gitignore. Попробуйте fdfind -H -I или rg -uu.
  • ❓ fd: command not found в Ubuntu. Команда называется fdfind, fd — только через псевдоним.
  • 🧱 Поток «Permission denied». Добавьте 2>/dev/null или запустите через sudo, если нужно искать и в закрытых папках.

Чек-лист

Частые вопросы

Чем find отличается от locate?

find каждый раз обходит диск и видит текущее состояние, зато может работать долго. locate ищет по базе, которая обновляется раз в сутки: отвечает мгновенно, но не знает о файлах, созданных после обновления. Для свежих файлов и сложных условий — find, для «где-то был файл с таким именем» — locate.

Как найти файл по части имени?

find . -iname "*часть*" — звёздочки с обеих сторон означают «что угодно до и после». В locate и fd звёздочки не нужны: locate часть, fdfind часть.

Как найти файл по всему компьютеру?

sudo find / -xdev -iname "*имя*" 2>/dev/null или locate -i имя. Ключ -xdev не даёт уходить на флешки и сетевые диски, а 2>/dev/null убирает сообщения об ошибках доступа.

Почему в Ubuntu нет команды fd?

Пакет называется fd-find, а команда — fdfind, потому что имя fd в Debian уже занято другой программой. Добавьте alias fd=fdfind в ~/.bashrc.

Как найти файл, в котором есть определённый текст?

grep -rl "текст" /путь выведет только имена файлов, grep -rn — ещё и строки с номерами. В проектах с git удобнее rg "текст": он быстрее и пропускает мусор вроде node_modules.

Как найти и удалить файлы старше N дней?

find /путь -type f -mtime +N — сначала посмотрите список, затем добавьте в конец -delete. Для регулярной очистки поставьте команду в cron.

Как узнать, где установлена программа?

command -v имя или type имя покажут, что именно запустится. whereis имя найдёт ещё и документацию, а dpkg -S $(command -v имя) подскажет, из какого пакета она пришла.

Чем grep отличается от ripgrep?

По смыслу ничем — оба ищут текст. grep есть везде и ведёт себя предсказуемо. ripgrep нужно поставить отдельно, зато он быстрее, сразу ищет рекурсивно и учитывает .gitignore. На сервере, где ничего лишнего нет, хватает grep -rn.

Статья помогла?

Комментарии

Пока никто не написал. Будьте первым — вопрос или свой опыт одинаково полезны.

Комментарий появится после проверки. Ссылки и реклама не публикуются.