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

Категория: Bash · Язык: Bash · Обновлено:

Команда find ищет файлы по имени, размеру, дате, типу и правам. Базовый вид: find где_искать условия действие. Например, find . -name "*.log" найдёт все файлы с расширением .log в текущей папке и во вложенных.

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

Bash
find . -name "report.txt"          # точное имя
find . -name "*.log"               # маска (кавычки обязательны)
find . -iname "readme*"            # без учёта регистра
find . -type f -name "*.py"        # только файлы
find . -type d -name "node_modules" # только папки

Кавычки вокруг маски нужны, иначе оболочка раскроет * ещё до запуска find.

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

Bash
find . -type f -size +100M          # больше 100 мегабайт
find . -type f -size -10k           # меньше 10 килобайт
find . -type f -size 0              # пустые файлы
find . -type f -size +100M -exec ls -lh {} +    # показать размеры найденных

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

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

Bash
find . -type f -mtime -1            # изменены за последние сутки
find . -type f -mmin -30            # изменены за последние 30 минут
find . -type f -newer config.ini    # новее файла config.ini

Для удаления по возрасту есть отдельная подробная заметка про -mtime +N -delete.

Права и владелец

Bash
find . -type f -perm 644            # точные права
find . -type f -perm -u+x           # владелец может выполнять
find . -type f -user anna           # принадлежат пользователю
find . -type f -empty               # пустые файлы

Ограничить глубину и исключить папки

Bash
find . -maxdepth 1 -type f                      # только текущая папка
find . -mindepth 2 -type f                      # пропустить верхний уровень
find . -type f -not -path "*/node_modules/*"    # без node_modules
find . -type f ! -name "*.tmp"                  # исключить по имени

Выполнить команду над найденным

Bash
find . -name "*.log" -exec wc -l {} \;          # по одному файлу на вызов
find . -name "*.log" -exec wc -l {} +           # пачками, быстрее
find . -name "*.py" -exec grep -l "TODO" {} +   # в каких файлах есть TODO
find . -name "*.tmp" -print0 | xargs -0 -r rm   # безопасно для пробелов в именах

Символ {} подставляется вместо имени файла. Завершение \; запускает команду для каждого файла отдельно, а + передаёт сразу много файлов.

Несколько условий

Bash
find . -type f \( -name "*.jpg" -o -name "*.png" \)    # jpg или png
find . -type f -name "*.log" -size +1M                 # логи больше 1 МБ (условия соединяются как «и»)

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

Как вывести только имена без пути?

Используйте -printf "%f\n" в GNU find: find . -name "*.txt" -printf "%f\n".

Почему find выводит Permission denied?

Нет прав на некоторые папки. Скройте ошибки: find / -name "app.conf" 2>/dev/null.

Чем find лучше locate?

locate быстрее, но работает по базе, которая обновляется раз в сутки. find всегда показывает актуальное состояние диска.