LinuxRuLinux без лишней теории
Командная строка

Поиск файлов в Linux: по имени, размеру, дате и содержимому

Редакция LinuxRu8 мин чтенияИнструкции

Поиск файлов в Linux по имени выполняют find (обход диска в реальном времени) и plocate (мгновенно, по базе), а поиск текста в файлах делают grep и ripgrep. Ниже рабочие примеры для каждой команды, разница между ними и готовые рецепты для частых задач.

Поиск файлов в Linux: по имени, размеру, дате и содержимому
Фото: Andrea `BaSh` Scarpino, GPL, Wikimedia Commons
Содержание
  1. Чем искать
  2. find по имени
  3. Размер и дата
  4. Действия с найденным
  5. locate и plocate
  6. grep по содержимому
  7. ripgrep и fd
  8. Готовые рецепты
  9. Частые вопросы

Чем искать файлы в Linux: какой инструмент для какой задачи

Поиск файлов в Linux делится на два вопроса: где лежит файл с таким именем и в каком файле встречается такой текст. Для первого есть find, который обходит каталоги прямо сейчас, и plocate, который ищет по заранее собранной базе. Для второго есть grep и его быстрый современный собрат ripgrep. Ещё есть fd, удобная замена find для повседневных задач.

ИнструментЧто ищетОсобенностьПакет: apt / dnf / pacman
findФайлы по имени, типу, размеру, дате, правамОбходит диск в реальном времени, есть всегдаfindutils, уже установлен
plocateФайлы по имениМгновенно, но по базе, которая обновляется раз в суткиplocate / plocate / plocate
grepТекст внутри файловЕсть везде, понимает регулярные выраженияgrep, уже установлен
ripgrep (rg)Текст внутри файловОчень быстрый, учитывает .gitignoreripgrep / ripgrep / ripgrep
fdФайлы по имениКороткий синтаксис, цветной выводfd-find / fd-find / fd

Если терминал для вас пока в новинку, начните со статьи Основные команды Linux для начинающих, а потом возвращайтесь сюда.

Команда find: поиск по имени и типу

Общий вид команды: find где условия действие. Если действие не указано, find просто печатает пути найденного.

# файл с точным именем в домашнем каталоге
find ~ -name "report.pdf"

# все PDF без учёта регистра: .pdf, .PDF, .Pdf
find ~ -iname "*.pdf"

# только каталоги с именем node_modules
find ~/projects -type d -name node_modules

# искать по всей системе, скрыв ошибки доступа
sudo find / -name "nginx.conf" 2>/dev/null

# не глубже двух уровней вложенности
find /etc -maxdepth 2 -name "*.conf"

# исключить каталог .git из поиска
find . -path ./.git -prune -o -name "*.py" -print

Шаблон всегда берите в кавычки. Без них оболочка сама раскроет *.pdf в список файлов текущего каталога ещё до запуска find, и результат будет странным. Тип задаётся буквой: f - обычный файл, d - каталог, l - символическая ссылка.

Условия по умолчанию объединяются через И. Для ИЛИ используйте -o и скобки, экранированные обратной косой чертой: find . \( -name "*.jpg" -o -name "*.png" \). Отрицание пишется через -not или !.

find примеры: размер, дата изменения, владелец и права

# файлы больше 500 МБ на корневом разделе
sudo find / -xdev -type f -size +500M 2>/dev/null

# пустые файлы и каталоги
find ~/Загрузки -empty

# изменённые за последние 7 дней
find ~/Документы -type f -mtime -7

# изменённые за последние 30 минут
find /etc -mmin -30

# новее, чем конкретный файл
find . -newer package.json

# принадлежащие пользователю www-data
sudo find /var/www -user www-data

# файлы, доступные на запись всем
find ~ -type f -perm -o+w

Суффиксы размера: k - килобайты, M - мегабайты, G - гигабайты, а плюс и минус означают больше и меньше. С датами есть тонкость: -mtime -7 считает полными сутками, поэтому -mtime 0 означает последние 24 часа, а не сегодняшний календарный день. Параметр -xdev не даёт find уходить на другие файловые системы, например на подключённые диски и /proc.

Поиск больших файлов обычно нужен, когда кончается место. Для этого есть и более удобные инструменты, они собраны в статье Как освободить место на диске в Linux. А как читать и менять права, найденные через -perm, объясняет материал Права доступа в Linux: chmod, chown, umask.

Что делать с найденным: -exec, -delete и xargs

# подробный список найденного
find . -name "*.log" -exec ls -lh {} +

# сжать каждый лог старше 30 дней
find /var/log/myapp -name "*.log" -mtime +30 -exec gzip {} \;

# спрашивать подтверждение перед каждым удалением
find ~/tmp -name "*.bak" -ok rm {} \;

# удалить временные файлы старше 14 дней
find ~/tmp -type f -mtime +14 -delete

# безопасная передача имён с пробелами в другую команду
find . -name "*.jpg" -print0 | xargs -0 du -ch | tail -n 1

Разница между окончаниями -exec: с \; команда запускается отдельно для каждого файла, с + find передаёт сразу пачку файлов, и это намного быстрее. Связка -print0 и xargs -0 нужна, чтобы имена с пробелами и переводами строк не разваливались на куски.

Перед -delete всегда запускайте ту же команду без него и смотрите список. И ставьте -delete последним: find выполняет выражение слева направо, и find . -delete -name "*.tmp" удалит всё в каталоге, а не только временные файлы.

locate и plocate: мгновенный поиск по базе

Если нужно просто найти, где лежит файл с известным именем, find по всему диску работает долго. plocate отвечает за доли секунды, потому что ищет в базе, собранной заранее. В свежих Debian, Ubuntu и Fedora он заменил старый mlocate, команда locate обычно ведёт на него же.

# установка
sudo apt install plocate    # Debian, Ubuntu
sudo dnf install plocate    # Fedora
sudo pacman -S plocate      # Arch

# построить или обновить базу вручную
sudo updatedb

# поиск подстроки в пути, без учёта регистра
locate -i vpn.conf

# сколько совпадений, без вывода списка
locate -c ".desktop"

# поиск по регулярному выражению
locate -r "/etc/.*\.conf$"

Базу обновляет таймер systemd plocate-updatedb.timer раз в сутки. Отсюда главное ограничение: файл, созданный час назад, locate не найдёт, пока база не обновится. Проверить таймер можно командой systemctl list-timers plocate-updatedb.timer. Каталоги, которые не надо индексировать, например точки монтирования сетевых дисков, перечисляются в /etc/updatedb.conf. plocate учитывает права: обычный пользователь не увидит в выдаче файлы из каталогов, куда у него нет доступа.

grep: поиск текста в файлах

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

# рекурсивно, с номерами строк, без учёта регистра
grep -rni "listen 443" /etc/nginx

# только имена файлов, где есть совпадение
grep -rl "API_KEY" ~/projects

# целое слово, а не часть другого
grep -rw "port" config/

# только в файлах с нужным расширением, пропуская каталог
grep -rn --include="*.py" --exclude-dir=".venv" "def main" .

# две строки контекста до и после совпадения
grep -C 2 "error" app.log

# расширенные регулярные выражения: ошибки или предупреждения
grep -E "error|warning" app.log

# строки, где совпадения НЕТ, например убрать комментарии
grep -v "^#" /etc/fstab

Ключ -c выводит число совпадающих строк, -o печатает только саму найденную часть. Для сжатых логов вроде syslog.2.gz есть zgrep с теми же опциями. grep отлично работает в конвейерах: ps aux | grep firefox или journalctl -b | grep -i usb. О конвейерах и перенаправлении подробнее в статье Терминал Linux: горячие клавиши, история команд и конвейеры.

ripgrep и fd: быстрые современные замены

ripgrep

rg по смыслу повторяет grep -rn, но по умолчанию ищет рекурсивно, пропускает скрытые файлы, двоичные файлы и всё из .gitignore. В больших репозиториях он заметно быстрее grep, потому что параллелит работу и не лезет в node_modules.

# рекурсивный поиск в текущем каталоге
rg "TODO"

# без учёта регистра, только в файлах Python
rg -i -t py "connection refused"

# по маске имени и включая скрытые файлы
rg --hidden -g "*.yaml" "image:"

# только список файлов
rg -l "deprecated"

fd

fd ищет файлы по имени с синтаксисом короче, чем у find: fd report вместо find . -iname "*report*". Регистр учитывается умно: если в шаблоне только строчные буквы, поиск без учёта регистра. В Debian и Ubuntu программа называется fdfind из-за конфликта имён, удобно сделать псевдоним alias fd=fdfind, как это сделать постоянным, описано в статье Aliases в Linux: удобные псевдонимы команд.

# все PDF в домашнем каталоге
fd -e pdf . ~

# каталоги с именем build
fd -t d build

# выполнить команду для каждого найденного файла
fd -e png -x optipng {}

Готовые рецепты для частых ситуаций

  • Найти, какой файл конфигурации задаёт параметр: sudo grep -rn "PasswordAuthentication" /etc/ssh/.
  • Десять самых больших файлов в домашнем каталоге: find ~ -type f -printf "%s %p\n" | sort -nr | head -n 10.
  • Что менялось в системе за последний час: sudo find /etc /usr -xdev -mmin -60 -type f.
  • Найти и открыть файл одним движением: xdg-open "$(locate -i -l 1 договор.pdf)".
  • Битые символические ссылки: find ~ -xtype l.
  • Файлы без владельца после удаления пользователя: sudo find / -xdev -nouser.

В графических окружениях тоже есть быстрый поиск: KRunner в KDE Plasma по Alt+Пробел и обзор GNOME по клавише Super ищут по индексу файлов. Но когда нужно найти что-то в системных каталогах, по размеру или по содержимому конфигов, терминальные инструменты надёжнее. Все условия find описаны в руководстве GNU findutils.

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

Как найти файл по имени в Linux?

Если файл существует давно, быстрее всего locate имя. Если нужен точный поиск прямо сейчас, используйте find ~ -iname "*имя*", а для поиска по всей системе sudo find / -iname "*имя*" 2>/dev/null.

Как найти текст во всех файлах папки?

Командой grep -rn "текст" /путь/к/папке. Добавьте -i, чтобы не учитывать регистр, и -l, если нужны только имена файлов. В больших проектах быстрее работает rg "текст".

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

locate и plocate ищут по базе, которую таймер обновляет раз в сутки. Выполните sudo updatedb, и файл появится в выдаче.

Чем отличается -exec с \; и с +?

С \; команда запускается отдельно для каждого найденного файла. С + find передаёт файлы пачками, это работает намного быстрее.

Как найти большие файлы в Linux?

Командой sudo find / -xdev -type f -size +500M 2>/dev/null. Параметр -xdev не даёт find уходить на другие разделы, а 2>/dev/null скрывает ошибки доступа.

Документация и источники

Читайте также

Команды проверены на актуальных версиях дистрибутивов на момент обновления. Перед изменением системных настроек сделайте резервную копию.