Администрирование FreeBSD, Linux, ... find: исключение папки из области поиска Wed, September 02 2026  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

find: исключение папки из области поиска Печать
Добавил(а) microsin   

Как в команде find исключить из поиска определенную папку?

Чтобы исключить папку из поиска в команде find, используйте параметр -path в сочетании с -prune.

Вот самый распространенный и правильный способ (искл_папка в пути поиска не будет просматриваться):

find /путь/поиска -path "/путь/поиска/искл_папка" -prune -o -name "*.txt" -print

Как это работает:

-path "/путь/поиска/искл_папка" — находит полный путь к папке, которую нужно исключить.
-prune — говорит find не заходить внутрь этой папки (обрубает ветку).
-o — логическое ИЛИ. Если условие с -path и -prune сработало, то остальная часть команды (-name) игнорируется. Если нет — выполняется поиск по имени.

Выглядит сложно, но ничего не поделаешь - этим мы платим за универсальность инструмента find.

Конкретные примеры:

1. Исключаем папку `cache` в текущей директории:

find . -path "./cache" -prune -o -name "*.log" -print

2. Исключаем папку на любом уровне вложенности (например, все папки `node_modules`):

find . -path "*/node_modules" -prune -o -name "*.js" -print

3. Исключаем сразу несколько папок (объединяем через `-o`):

find . \( -path "./tmp" -o -path "./backup" \) -prune -o -name "*.txt" -print

Важный нюанс (частая ошибка). Если вы пишете:

find . -path "./cache" -prune -name "*.log"   # ❌ НЕПРАВИЛЬНО

... то find найдет файлы *.log только внутри папки cache, а не снаружи.

Чтобы искать снаружи, всегда используйте конструкцию с -o и обязательно ставьте `-print` в конце:

find . -path "./cache" -prune -o -name "*.log" -print   # ✅ ПРАВИЛЬНО

Альтернативный способ исключения папки (через grep -v). Если вам нужно исключить папку, но она находится глубоко и с -prune разобраться сложно, можно отфильтровать результат через grep:

find . -name "*.txt" | grep -v "./cache/"

Минус: этот способ медленнее, так как find всё равно сначала обойдет всю папку cache (это может быть долго, если папка большая), а потом просто скроет результат. -prune же физически пропускает обход, что намного быстрее.

[Как для find исключить несколько папок?]

Для исключения нескольких папок в find нужно объединить условия через -o (логическое ИЛИ) в группах с -prune. Группа определяется скобками, которые нужно экранировать символом '\'.

Вот универсальный шаблон:

find . \( -path "./папка1" -o -path "./папка2" -o -path "./папка3" \) -prune -o -name "*.txt" -print

Ключевые моменты:

\( ... \) — группировка условий.
-o — операция ИЛИ (исключаем, если путь совпадает с любой из перечисленных папок).
После -prune обязательно ставим -o и -print (или другое действие).

Конкретные примеры:

1. Исключаем из поиска папки cache, tmp и backup в текущей директории:

find . \( -path "./cache" -o -path "./tmp" -o -path "./backup" \) -prune -o -name "*.log" -print

2. Исключаем папки на любом уровне вложенности (например, все node_modules, .git и dist):

find . \( -path "*/node_modules" -o -path "*/.git" -o -path "*/dist" \) -prune -o -name "*.js" -print

3. Исключаем папки с пробелами или спецсимволами в имени (с помощью двойных кавычек):

find . \( -path "./My Documents" -o -path "./Downloads" \) -prune -o -name "*.pdf" -print

Если папок много — используйте переменную или файл.

Вариант A: список в переменной окружения (через -o):

exclude_dirs="-path ./cache -o -path ./tmp -o -path ./backup"
find . \( $exclude_dirs \) -prune -o -name "*.txt" -print

Вариант B: через bash-массив (удобно, если пути сложные):

exclude=("./cache" "./tmp" "./backup")
# Собираем условие:
for dir in "${exclude[@]}"; do
    args+=(-path "$dir" -o)
done
# Убираем последний -o
unset 'args[${#args[@]}-1]'

find . \( "${args[@]}" \) -prune -o -name "*.txt" -print

Вариант C: читаем список из файла (по одной папке на строку):

# files.txt содержит:
# ./cache
# ./tmp
# ./backup

find . $(awk '{print "-path " $1 " -o"}' files.txt | sed '$ s/-o$//') -prune -o -name "*.txt" -print

Альтернатива (проще, но медленнее). Если папок много и производительность не критична, можно отфильтровать через `grep -v` с опцией `-E` (расширенными регулярками):

find . -name "*.txt" | grep -v -E "(./cache|./tmp|./backup)"

Или исключить папки на любом уровне:

find . -name "*.txt" | grep -v -E "(node_modules|\.git|dist)"

Минус: find всё равно физически обходит исключённые папки, что может быть медленно для больших директорий (например, node_modules). Если использовать -prune, то будет быстрее, так как пропускает обход.

Частая ошибка исключения папок, так делать неправильно:

find . -path "./cache" -prune -o -path "./tmp" -prune -o -name "*.txt" -print

Работать будет, но если папок много — код становится громоздким и нечитаемым. Лучше группировать все условия в одни скобки перед одним -prune.

Правильно:

find . \( -path "./cache" -o -path "./tmp" \) -prune -o -name "*.txt" -print

 

 

Добавить комментарий


Защитный код
Обновить

Top of Page