Вопрос или проблема
У меня следующая структура директорий на машине под управлением macOS:
dir1/
|- file1.txt
|- dir2/
|- file2.txt
|- dir3
|- file3.txt
Затем я запускаю следующие две команды find
:
find . -depth 1 -path '*.txt'
find . -mindepth 1 -maxdepth 1 -path '*.txt'
Цель состоит в том, чтобы нерекурсивно искать все файлы с расширением .txt
в dir1
. Если использовать в dir1
, обе команды возвращают file1.txt
, но мне сказали, что только вторая команда, с параметрами -mindepth
и -maxdepth
, является действительно корректной. Так ли это? Мог бы кто-то объяснить разницу?
И второй вопрос. Если мне нужно искать рекурсивно, следует ли полностью убрать -mindepth 1 -maxdepth 1
или нужно убрать только -maxdepth 1
?
-depth 1
из FreeBSD является условным предикатом, который возвращает true, если файл, который в данный момент рассматривается, находится на глубине 1, но это не останавливает find
от продолжения ниже глубины 1.
-mindepth 1
/ -maxdepth 1
из GNU являются опциональными предикатами (в терминологии GNU find
), которые глобально влияют на поведение find
. Они оба всегда возвращают true (и в общем случае вы хотите, чтобы они были в начале и не зависеть от их результата),
-mindepth 1
гарантирует, что ни один файл на глубине ниже 1 никогда не будет выбран / не будет обработан-maxdepth 1
заставляетfind
не углубляться ниже уровня 1.
-depth 1
может быть полезным для выполнения различных действий в зависимости от глубины, например:
find . -depth 1 -exec printf '"%s" is in the current directory\n' {} ';' -o \
-depth +1 -exec printf '"%s" is below the current directory\n' {} ';'
Но чтобы обрабатывать только файлы на глубине 1,
find . -mindepth 1 -maxdepth 1 ...
Или стандартный эквивалент:
find . -name . -prune -o ....
Это то, что вам нужно.
Ответ или решение
Сравнение команд find . -depth 1 -path '*.txt'
и find . -mindepth 1 -maxdepth 1 -path '*.txt'
Введение
При работе с командами поиска файлов в Unix-подобных системах, таких как macOS, важно понимать разницу между различными параметрами команды find
. В данном случае мы сравниваем два подхода: -depth 1
и комбинацию -mindepth 1 -maxdepth 1
. Оба этих параметра могут вернуть нужные файлы, но они делают это разными способами, что определяет их корректность в зависимости от целей поиска.
Разбор параметров
-
-depth 1
:- Этот параметр является условным предикатом, который возвращает значение
true
, если обрабатываемый файл находится на первом уровне вложенности. Однако это не предотвращает рекурсивное прохождение командыfind
по подкаталогам. То есть, хотя вы, возможно, получитеfile1.txt
, команда также будет просматривать подкаталоги (например,dir2
иdir3
) на наличие других файлов, включая текстовые файлы в них.
- Этот параметр является условным предикатом, который возвращает значение
-
-mindepth 1 -maxdepth 1
:- Эти параметры являются опциональными предикатами, которые определяют поведение команды
find
глобально. -mindepth 1
гарантирует, что будут выбраны только файлы на уровне 1 или глубже, игнорируя файлы на нулевом уровне. Это означает, что не будет обрабатываться сам каталог, в котором вы ищете.-maxdepth 1
ограничивает глубину поиска, не позволяя командеfind
выходить за пределы первого уровня вложенности. Таким образом, поиск осуществляется только на текущем уровне (то есть вdir1
), что предотвращает просмотр файлов в подкаталогах.
- Эти параметры являются опциональными предикатами, которые определяют поведение команды
Почему более корректен второй вариант?
В первом варианте (-depth 1
) результаты могут оказаться не полными или содержать нежелательные файлы из подкаталогов. Хотя оба варианта возвращают file1.txt
при выполнении в dir1
, только второй вариант действительно соответствует вашему пожеланию "нерекурсивно" искать текстовые файлы на текущем уровне.
Рекомендация по рекурсивному поиску
Если вам необходимо осуществить рекурсивный поиск текстовых файлов, рекомендуется удалить параметр -mindepth 1
. Удаляя только -maxdepth 1
, вы позволяете команде find
осуществлять поиск по всем уровням вложенности, начиная с текущего каталога.
Таким образом, команда может выглядеть так:
find . -path '*.txt'
Или, для явного указания:
find . -name '*.txt'
Заключение
Понимание функций различных предикатов find
критически важно для эффективного поиска файлов в файловой системе. Выбор между -depth
и -mindepth/-maxdepth
зависит от ваших целей: хотите ли вы ограничить поиск только текущим уровнем или готовы исследовать вложенные каталоги. Таким образом, использование параметров -mindepth
и -maxdepth
предлагает более точные и предсказуемые результаты при специфических задачах поиска.