linux-labs

Вики / Базовые команды

find (поиск файлов)

Команда GNU findutils БазовоеФайлы

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

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

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

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

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   # пропустить каталог
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).

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.

find . -name "*.log"              # по имени (в кавычках!)
find . -type f -size +100M        # крупные файлы
find . -mtime -1                  # изменён за сутки
find . -name "*.tmp" -delete      # удалить (сперва проверь без -delete!)
find . -type f -exec chmod 644 {} +
find . -printf '%s %p\n' | sort -rn | head   # топ по размеру
find DIR -path EXCL -prune -o -name PAT -print  # с исключением каталога

См. также