ServerAID
Найти гайд, команду, тег… ⌘ K
Shell и скрипты

find в Linux: руководство по поиску файлов с примерами для Ubuntu

find — самый мощный инструмент поиска файлов в Linux. В отличие от locate он смотрит файловую систему вживую, поддерживает фильтрацию по имени, размеру, времени изменения, правам, владельцу и умеет выполнять действие над найденным. Разбираем синтаксис, ключевые предикаты и десяток рецептов, которые покрывают 95% реальных задач администратора Ubuntu.

Зачем нужен find

find — стандартная утилита поиска файлов в Linux. На Ubuntu она уже установлена в составе coreutils, отдельно ставить не нужно. В отличие от locate, который ищет по предварительно построенному индексу mlocate.db, find обходит файловую систему в реальном времени — поэтому видит свежесозданные файлы и работает на любом смонтированном каталоге, включая сетевые шары и временные файловые системы.

Главные сценарии использования:

  • Найти файлы по маске имени в большом дереве каталогов.
  • Найти всё, что не открывалось дольше 30 дней — для очистки.
  • Найти файлы тяжелее 1 ГБ, которые забивают диск.
  • Найти файлы с неправильными правами доступа.
  • Применить команду к каждому найденному файлу — массовое переименование, удаление, чмоды.

Базовый синтаксис

find [где_искать] [условия] [действие]
  • [где_искать] — путь, с которого начать обход. Если опущен — текущая директория ..
  • [условия] (predicates) — фильтры: -name, -type, -size, -mtime и десятки других.
  • [действие] — что сделать с найденным. По умолчанию — -print (вывести путь в stdout).

Самый простой пример — найти все файлы в текущей директории и её поддиректориях:

find .

Большая часть реальной работы — комбинации условий и одно действие.

Поиск по имени

-name — поиск по точному совпадению имени файла. Поддерживает шаблоны: *, ?, […].

# Все .conf файлы в /etc
sudo find /etc -name "*.conf"

# Конкретный файл по имени
find ~ -name "report.pdf"

# Несколько расширений сразу
find /var/log -name "*.log" -o -name "*.gz"

-iname — то же, но без учёта регистра:

find . -iname "readme*"   # найдёт README, ReadMe, readme.md, README.txt

Шаблоны интерпретируются самим find, не shell — поэтому обязательно в кавычках, иначе bash раскроет * до запуска find.

Поиск по типу

-type фильтрует по типу объекта:

Код Что значит
f обычный файл
d директория
l симлинк
b блочное устройство
c символьное устройство
p named pipe
s сокет
# Только директории с именем .git
find / -type d -name ".git" 2>/dev/null

# Все симлинки в /usr/bin
find /usr/bin -type l

# Файлы без типа директории — например, для подсчёта только файлов
find . -type f | wc -l

2>/dev/null гасит ошибки доступа — типичные при обходе системных каталогов без sudo.

Поиск по размеру

-size принимает число с суффиксом:

Суффикс Единица
c байт
k килобайт (1024)
M мегабайт
G гигабайт
без суффикса блок 512 байт
# Файлы тяжелее 1 ГБ
find / -type f -size +1G 2>/dev/null

# Файлы между 10 и 100 МБ
find . -type f -size +10M -size -100M

# Пустые файлы
find . -type f -size 0c

# Маленькие .log файлы
find /var/log -name "*.log" -size -1M

Префиксы: +N больше N, -N меньше N, N точно равно N.

Поиск по времени

Три времени каждого файла:

  • mtime — modification time, когда последний раз менялось содержимое.
  • atime — access time, когда последний раз читалось.
  • ctime — change time, когда последний раз менялись метаданные (права, владелец, имя).

Числа — в днях:

# Файлы, изменённые за последние 7 дней
find /var/log -type f -mtime -7

# Файлы, не открывавшиеся больше 30 дней
find /home -type f -atime +30

# Файлы, у которых изменилось что угодно за последний день
find / -type f -ctime -1 2>/dev/null

Для минут и часов есть -mmin, -amin, -cmin:

# Изменения за последние 5 минут (полезно для отладки)
find /etc -mmin -5

Если нужно сравнение со временем конкретного файла — -newer:

# Файлы, изменённые позже /tmp/marker
find . -newer /tmp/marker

Поиск по правам

-perm принимает права в восьмеричной или символической записи:

# Файлы с правами ровно 0644
find . -type f -perm 0644

# Файлы, у которых разрешена запись для всех (other-write)
find / -type f -perm /o=w 2>/dev/null

# Файлы с SUID-битом
find / -type f -perm /4000 2>/dev/null

# Скрипты, доступные только владельцу (700)
find ~/scripts -type f -perm 0700

Префиксы:

  • 0644 — точное совпадение.
  • -0644 — все указанные биты должны быть выставлены (может быть больше).
  • /0644 — хотя бы один из указанных битов выставлен.

-perm /4000 — классический SecOps-запрос: найти все файлы с SUID-битом, который часто становится вектором эскалации привилегий.

Поиск по владельцу

# Файлы пользователя deploy
find /var -user deploy

# Файлы группы www-data
find /var/www -group www-data

# Файлы без валидного владельца (сирые)
find / -nouser 2>/dev/null
find / -nogroup 2>/dev/null

-nouser / -nogroup — полезны для аудита после удаления учётных записей, чтобы найти зависшие файлы.

Сложные условия

find поддерживает логические операторы:

# И (по умолчанию между условиями)
find . -type f -name "*.log"

# Явное И
find . -type f -a -name "*.log"

# ИЛИ
find . -name "*.log" -o -name "*.gz"

# НЕ
find . -type f -not -name "*.tmp"

# Группировка через экранированные скобки
find . \( -name "*.log" -o -name "*.txt" \) -type f -mtime -7

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

Действия над найденным

По умолчанию find печатает путь к найденному. -ls — выводит как ls -l:

find /var/log -name "*.log" -ls

-delete

Удаляет найденное. Опасный режим — без find сначала через -print посмотрите, что попадёт под удаление.

# Сначала проверка
find /tmp -type f -mtime +7

# Потом удаление
find /tmp -type f -mtime +7 -delete

-exec

Выполняет произвольную команду. {} — место подстановки имени найденного файла. Заканчивается на \;.

# Изменить права на все .sh скрипты
find ~/scripts -name "*.sh" -exec chmod +x {} \;

# Скопировать все .conf файлы в бэкап
find /etc -name "*.conf" -exec cp {} /backup/etc/ \;

# Удалить старые логи с подтверждением
find /var/log -name "*.log" -mtime +30 -ok rm {} \;

-ok — то же, что -exec, но запрашивает подтверждение перед каждой командой.

-exec ... +

Альтернативный синтаксис -exec: вместо \; использовать +. Тогда find соберёт несколько найденных файлов в одну команду — быстрее при больших объёмах.

# Медленно: запуск chmod на каждый файл
find . -name "*.sh" -exec chmod +x {} \;

# Быстро: один chmod на пачку файлов
find . -name "*.sh" -exec chmod +x {} +

find + xargs

Альтернатива -exec — конвейер через xargs:

find . -name "*.log" | xargs gzip

Главная гошка xargs: если в именах файлов есть пробелы или спецсимволы — сломается. Решение — флаги -print0 у find и -0 у xargs:

find . -name "*.log" -print0 | xargs -0 gzip

Между -exec ... + и xargs разница в производительности почти не заметна; выбор — вопрос привычки.

Десять рецептов на каждый день

# 1. Топ-10 самых больших файлов в /var
sudo find /var -type f -exec du -h {} + 2>/dev/null | sort -rh | head

# 2. Все .pid файлы (демоны)
sudo find /var/run -name "*.pid"

# 3. Файлы, открытые на запись для всех (мира)
sudo find / -type f -perm -o=w 2>/dev/null

# 4. SUID-программы (аудит безопасности)
sudo find / -type f -perm /4000 2>/dev/null

# 5. Пустые директории
find /opt -type d -empty

# 6. Сжать все .log старше недели
sudo find /var/log -name "*.log" -mtime +7 -exec gzip {} +

# 7. Найти и удалить .DS_Store от macOS
find . -name ".DS_Store" -delete

# 8. Файлы определённого пользователя в /tmp
sudo find /tmp -user nobody

# 9. Симлинки, ведущие в никуда (broken)
find / -type l ! -exec test -e {} \; -print 2>/dev/null

# 10. Сменить владельца на www-data для всех .php
sudo find /var/www -name "*.php" -exec chown www-data:www-data {} +

find vs locate vs which

Три похожих инструмента, разные задачи:

Утилита Что ищет Где Скорость Свежесть
find по любому критерию в реальной ФС медленно на больших деревьях актуально
locate по имени в предварительном индексе mlocate.db мгновенно до последнего updatedb (обычно раз в сутки)
which исполняемые в $PATH только в каталогах из PATH мгновенно актуально
whereis бинарь + man + исходники по стандартным путям мгновенно актуально

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

locate на Ubuntu 24.04 в стандартной поставке нет — устанавливается отдельно:

sudo apt install plocate
sudo updatedb  # пересобрать индекс
locate hosts

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

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

find обходит файловую систему в реальном времени и поддерживает фильтры по размеру, времени, правам и так далее. locate ищет только по имени, но мгновенно — потому что использует заранее построенный индекс mlocate.db. Если важна актуальность данных или нужны сложные фильтры — find; если нужно быстро найти файл по имени в стабильной системе — locate.

Как использовать find с пробелами в именах файлов?

Если просто find ... | xargs ..., пробелы в именах сломают команду. Решение — использовать null-разделитель: find . -name "*.txt" -print0 | xargs -0 grep "TODO". Альтернатива — find ... -exec ... {} +, который автоматически экранирует имена.

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

find <путь> -type f -mtime +<N> -delete. Перед удалением обязательно проверьте список без -delete, чтобы не снести нужное. Например, очистка /tmp от файлов старше недели: find /tmp -type f -mtime +7 -delete.

Почему find выводит ошибки «Permission denied»?

Это нормально при обходе системных каталогов без sudo. Глушите их так: find / -name "*.conf" 2>/dev/null. Если нужны и системные файлы — запускайте через sudo find /....

Можно ли использовать регулярные выражения вместо шаблонов?

Да, флаг -regex (соответствует всему пути, не только имени) и -iregex для регистронезависимого варианта. Тип регулярки выбирается опцией -regextype: posix-basic, posix-extended, emacs, posix-egrep. Пример: find . -regextype posix-extended -regex ".*\\.(jpg|png|gif)$".

Что запомнить

  • find — поиск в реальном времени с любыми фильтрами; не требует индекса.
  • Базовый синтаксис: find <путь> <условия> <действие>.
  • Ключевые предикаты: -name, -type, -size, -mtime, -perm, -user.
  • Шаблоны имени всегда в кавычках, иначе bash раскроет * до find.
  • Логические операторы: -a (по умолчанию), -o, -not, группировка через \( \).
  • Действия: -print (дефолт), -delete, -exec ... +, -ok (с подтверждением).
  • Для конвейера через xargs — обязательно -print0 и -0.
  • find — медленный, но точный; для быстрого поиска по имени — plocate.

Похожие материалы

Shell и скрипты

awk в Linux: обработка табличных данных и логов с примерами

awk — миниатюрный язык программирования для построчной обработки текста. Идеально подходит для работы с таблицами, CSV, логами и любыми данными со столбцами: автоматически разделяет каждую строку на поля и даёт удобный синтаксис фильтрации и преобразования. Разбираем базовый синтаксис, переменные, шаблоны, действия и десяток рецептов для повседневной работы администратора Ubuntu.

Редакция
Shell и скрипты

grep в Linux: поиск по тексту с регулярками и примерами для Ubuntu

grep — главный инструмент поиска по содержимому файлов в Linux. Умеет работать с регулярными выражениями POSIX и PCRE, рекурсивно обходить директории, считать совпадения, показывать контекст вокруг строки. Разбираем синтаксис, ключевые флаги, тонкости с регулярками и десяток рецептов для повседневной работы администратора Ubuntu.

Редакция
Shell и скрипты

sed на Linux: замена строк, правка in-place и регулярки

sed (stream editor) — стандартная команда Linux для построчной обработки текста: замена, удаление, печать строк по шаблону. Работает с потоком (pipe) или файлами, поддерживает in-place редактирование. Базовый инструмент шелл-скриптов после `grep` и `awk`.

Редакция
Shell и скрипты

wget на Linux: скачивание файлов, дозакачка и зеркало сайта

wget — стандартная утилита Linux для скачивания файлов по HTTP, HTTPS и FTP. Умеет дозакачивать прерванное, ходить рекурсивно по ссылкам, ограничивать скорость и работать без интерактива — поэтому это базовый инструмент скриптов установки, скачивания дистрибутивов и зеркалирования сайтов.

Редакция