Поиск файлов через find: условия, действия и безопасное удаление
Автор: Казачкин Даниил Михайлович · Обновлено
Утилита find обходит дерево каталогов и проверяет каждый путь по заданным условиям. В отличие от поиска по заранее построенному индексу она видит текущее состояние файловой…
Утилита find обходит дерево каталогов и проверяет каждый путь по заданным условиям. В отличие от поиска по заранее построенному индексу она видит текущее состояние файловой системы и умеет отбирать объекты по имени, типу, времени, размеру и правам.
Область обхода и выражение
Первый аргумент задаёт стартовый каталог. Далее идёт выражение: проверки обычно соединяются неявным AND, а действия выполняются только для совпавших путей.
mkdir -p /tmp/find-demo/src /tmp/find-demo/cache
printf 'const ready = true;\n' >/tmp/find-demo/src/app.ts
printf 'old cache\n' >/tmp/find-demo/cache/result.log
find /tmp/find-demo -type f -name '*.ts' -print
find /tmp/find-demo -type f -size +5c -printf '%s %p\n'-type f исключает каталоги, -name сравнивает только последнее имя, а -path — весь путь. Шаблон нужно заключать в кавычки, иначе его раньше времени раскроет shell относительно текущего каталога.
Исключение поддеревьев и приоритет
-prune не даёт descend внутрь совпавшего каталога. Операторы AND и OR имеют приоритет, поэтому сложное выражение лучше группировать экранированными скобками.
find /tmp/find-demo \
-path '*/cache' -prune -o \
-type f \( -name '*.ts' -o -name '*.js' \) -printБез явного -print некоторые действия ничего не выводят. Сначала стройте проверяемый список, затем добавляйте изменение.
Безопасная передача найденных имён
Имена файлов могут содержать пробелы и даже переводы строк. Конструкция find ... | xargs command без протокола NUL ломает такие пути. Надёжные варианты — -exec command {} + или пара -print0 | xargs -0.
find /tmp/find-demo -type f -name '*.log' -exec wc -c -- {} +
find /tmp/find-demo -type f -print0 | xargs -0 -r printf '<%s>\n'Маркер -- завершает опции утилиты, чтобы имя вроде -rf не стало флагом.
Ошибка и диагностика
Опасная ошибка — сразу применять -delete к непроверенному выражению. Покажите кандидатов через -print, ограничьте стартовый каталог абсолютным ожидаемым путём и проверьте число строк. Помните, что -delete влияет на порядок обхода и не сочетается с бездумным -prune. Для критичного сценария сначала перемещайте найденное в карантин.
Практика
Создайте дерево с исходниками, логами и каталогом vendor. Найдите только .log старше заданного времени, не заходя в vendor; вместо удаления выведите размер и путь через -exec. Добавьте файл с пробелом и убедитесь, что он обработан одним аргументом.
Что важно запомнить
- Всегда задавайте узкую стартовую точку и отдельно проверяйте выражение.
- Кавычки сохраняют glob для самого
find, а скобки делают приоритет явным. - Для произвольных имён используйте
-exec ... {} +или NUL-разделители.
Частые вопросы
Чем -name отличается от -path?
-name проверяет basename одного объекта, а -path сопоставляет путь целиком относительно формы, которую выдаёт обход.
Почему find ничего не удалил, но вернул ноль?
Пустое множество совпадений не считается ошибкой обхода. Если требуется хотя бы один файл, отдельно посчитайте кандидатов и проверьте бизнес-условие.
Когда нужен locate?
locate быстро ищет по периодически обновляемому индексу, но может не видеть свежие изменения. Для автоматизации над текущим деревом надёжнее find.