С чего начать Первые шаги трек · 15 ступеней
Linux Labs

find — поиск файлов

4 мин GNU findutils

Поиск файлов по имени, размеру, времени, правам; действия над найденным.

Шпаргалка

9 команд Версия для печати
  • find /etc -name nginx.conf точное имя, поиск от /etc
  • find ~ -type f -name site.conf только файлы, без каталогов
  • find . -name "*.log" по шаблону (шаблон — в кавычках!)
  • find . -type f -size +100M крупные файлы
  • find . -mtime -1 изменён за сутки
  • find . -name "*.tmp" -delete удалить (сперва проверь без -delete!)
  • find . -type f -exec chmod 644 {} + права 644 всем найденным файлам
  • find . -printf '%s %p\n' | sort -rn | head топ по размеру
  • find . -path './node_modules' -prune -o -name '*.js' -print с исключением каталога

Обзор

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

bash
find <где> <условия> <действие>
find /var/log -name "*.log"       # по имени

Без действия по умолчанию -print (печатает пути). Условия комбинируются: рядом = И; -o = ИЛИ; !/-not = НЕ; группировка \( ... \).

Ключи

10

Ниже — основные условия и действия find; полный список — man find.

Ключ Что делает Пример
-name pattern Отобрать по имени файла (glob-шаблон, учитывает регистр). find . -name "*.log"
-type f|d|l Отобрать по типу — обычный файл, каталог или символическая ссылка. find . -type f
-size +N|-N Отобрать по размеру (+ больше, - меньше; k/M/G — единицы). find . -size +100M
-exec command {} + Выполнить команду над найденным; {} + группирует аргументы пачкой. find . -type f -name "*.sh" -exec chmod +x {} +
-iname pattern Как -name, но без учёта регистра. find . -iname "*.JPG"
-mtime +N|-N Отобрать по времени изменения в сутках (-mmin — в минутах). find . -mtime -1
-maxdepth N Ограничить глубину обхода; ставь до условий. find . -maxdepth 2 -name "*.conf"
-xdev Не переходить границы файловой системы (пропустить примонтированное). find / -xdev -name '*.iso'
-delete Удалить каждый найденный файл; сначала проверь без этого ключа. опасно find . -name "*.tmp" -delete
-prune Не спускаться в отобранный каталог (вместе с -path и -o для исключений). find . -path './node_modules' -prune -o -name '*.js' -print

Ничего не найдено. Попробуй запрос короче.

Рецепты

2

Условия

bash
find . -name "*.conf"             # по имени (учитывает регистр)
find . -iname "*.JPG"             # без учёта регистра
find . -regex '.*/.*\.(log|tmp)'  # по регэкспу полного пути
find . -type f                    # только файлы (d каталоги, l ссылки)
find . -size +100M                # больше 100 МБ (-100k меньше 100 КБ)
find . -mtime -1                  # изменён за последние сутки (-mmin -10 — за 10 мин)
find . -newer /tmp/marker         # новее файла-метки
find . -user alice -group devs    # владелец/группа
find . -perm -4000                # SUID-файлы (аудит безопасности)
find . -empty                     # пустые файлы/каталоги
find /home -xdev -name '*.iso'    # не пересекать точки монтирования
find . -path './node_modules' -prune -o -name '*.js' -print   # пропустить каталог

Действия

bash
find . -name "*.tmp" -delete                      # удалить найденное
find . -name "*.log" -mtime +30 -delete           # логи старше 30 дней
find . -type f -name "*.sh" -exec chmod +x {} +   # сделать исполняемыми (+ = пачкой)
find . -type d -exec chmod 755 {} +               # права каталогам
find . -name "*.conf" -exec grep -l TODO {} +     # грепнуть по найденным
find . -name "*.bak" -ok rm {} \;                 # -ok = спросить подтверждение
find . -name "*.bak" -print0 | xargs -0 rm        # через xargs (имена с пробелами)
find . -type f -printf '%s %p\n' | sort -rn | head # крупнейшие файлы (-printf)

{} + группирует аргументы (быстрее), {} \; — по одному. -print0/xargs -0 безопасны для имён с пробелами (см. xargs).

Неполадки

5

Permission denied засоряет вывод

Отбрось ошибки: find / -name foo 2>/dev/null.

Ищет слишком глубоко / на других ФС

-maxdepth N ограничит глубину (ставь ДО условий), -xdev не пересекать монтирования (см. mount).

Случайно удалил не то с -delete

Всегда сперва прогоняй без действия (только вывод), убедись в списке, потом -delete/-exec rm. -delete подразумевает -depth — порядок условий важен.

find с -name ничего не находит

Шаблон должен быть в кавычках ("*.log"), иначе его раскроет шелл до find. Для регистронезависимости — -iname.

-exec медленный

{} \; запускает команду на каждый файл. Меняй на {} + (пачкой) или xargs.

См. также

  • grep — Поиск строк по шаблону; регулярки, рекурсия, контекст.
  • disk-usage — Куда делось место и inode — df, du, поиск крупных файлов, ловушки.
  • chmod-chown — Смена прав (chmod) и владельца/группы (chown) — числовой и символьный синтаксис.
Загрузка…