Я хочу найти все каталоги с определенной строкой, чтобы я мог еще раз найти файлы, содержащиеся внутри.
Поэтому я не хочу тратить время ./my-search-term/dir/my-search-term
и т. Д.
Как я могу прекратить повторение, когда я нашел первый каталог my-search-term?
Ответы:
-prune
Действие делаетfind
не рекурсию в каталог. Вы можете комбинировать это с другим действием, таким как-exec
(порядок-prune
и-exec
не имеет значения, если-prune
выполняется в любом случае).Обратите внимание, что вложение
find
внутри afind -exec
может быть немного проблематичным: вы не можете использовать-exec
во внутреннемfind
, потому что терминатор будет рассматриваться как терминатор внешнимfind
. Вы можете обойти это, вызывая оболочку, но остерегайтесь цитирования.источник
-prune
возвращает true и может быть поставлено перед-exec
.-o
Наверное, привычка иметь там. И я полагаю, что размещение-prune
перед-exec
более читабельным.-prune
опцию раньше.mkdir -p x1 x2; touch x1/x11 x1/x12 x2/x21 x2/x22; find . -name 'x1*' -exec rm -rf {} \;
выдает ошибку:find: ./x1: No such file or directory
. Решение состоит в том, чтобы добавить-prune
в концеfind
команды.find
раскрываются{}
даже тогда, когда он появляется в качестве подстроки аргумента для-exec
. Такая версияfind
захлебнется вашей второй командой, потому что команда{}
во внутреннейfind
команде (в команде оболочки) будет заменена именем директории, найденной во внешнейfind
. Вы можете это исправить, сказавfind . -name my-search-term -prune -exec sh -c 'find "$0" … -exec … "{"} +' {} \;
ie, используя"{"}
, во что превратится оболочка{}
. … (Продолжение)- голые решения -
Если вы хотите
find
пропустить содержимое найденного каталога, но продолжить поиск в других каталогах, используйте-prune
как предложено @laebshade. Полная команда должна выглядеть такС другой стороны, если вы хотите ,
find
чтобы полностью прекратить поиск и после нахождения первого каталога соответствия, то , что вы ищете-quit
(начиная с версии4.2.3
оGNU find
). Этот вариант немного сложнее в использовании, потому что онfind
немедленно завершает работу, поэтому его-quit
нужно поместить в самый конец команды:Для того, чтобы это работало, как и ожидалось, нужно убедиться, что
-exec
возвращается true (другими словами, нулевой статус). Если вы хотите, чтобы статус выхода-exec
игнорировался, чтобы он-quit
всегда работал, вам понадобится небольшой трюк:или
или
- некоторые объяснения -
Самая важная вещь о том, как
find
работает, состоит в том, что все действия («тесты») рассматриваются как логические предикаты, интерпретируемые слева направо. Поэтому последнее действие (например-quit
) будет выполнено только в том случае, если вся предыдущая часть не вернула false . По умолчанию все тесты объединяются с логическим «И»,-o
опция меняет соединение на «ИЛИ».Хитрый элемент в
-o
том, чтоfind
может "оптимизировать" вашу команду и не запускать-exec
часть, если вы просто наберетеЧтобы справиться с этим, вы можете принудительно
find
оценить все предикаты, обозначенные «ИЛИ», заключив их в круглые скобки.источник