Я хочу знайти всі каталоги з певним рядком, щоб я міг ще раз знайти файли, що містяться в ньому.
Тому я не хочу витрачати час на ./my-search-term/dir/my-search-termтощо.
Як я можу припинити повторення, коли знайшов перший каталог мого пошуку?
Я хочу знайти всі каталоги з певним рядком, щоб я міг ще раз знайти файли, що містяться в ньому.
Тому я не хочу витрачати час на ./my-search-term/dir/my-search-termтощо.
Як я можу припинити повторення, коли знайшов перший каталог мого пошуку?
Відповіді:
-pruneДія робить findНЕ рекурсию в каталог. Ви можете комбінувати його з іншою дією, такою як -exec(порядок -pruneі -execне має значення, якщо -pruneвиконується в будь-якому випадку).
find . -name my-search-term -prune -exec find {} … \;
Зауважте, що гніздування findвсередині find -execможе бути трохи проблематичним: ви не можете використовувати -execвнутрішній find, оскільки термінатор буде розглядатися як термінатор зовнішнім find. Ви можете обійти це шляхом виклику оболонки, але остерігайтеся цитування.
find . -name my-search-term -prune -exec sh -c '
find "$@" … -exec … {\} +
' _ {} +
-pruneповертає істину і може бути поставлено перед -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команда (в команді shell) буде замінена на ім'я каталогу, знайденого у зовнішній find. Ви можете це виправити, сказавши, find . -name my-search-term -prune -exec sh -c 'find "$0" … -exec … "{"} +' {} \; тобто, використовуючи "{"}, в яку оболонка перетвориться {}. … (Продовження)
Якщо ви хочете findпропустити вміст знайденого каталогу, але продовжувати пошук в інших каталогах, використовуйте -pruneяк запропоновано @laebshade. Потім повинна виглядати повна команда
find . -type d -name somename -prune -exec ...
З іншого боку, якщо ви хочете , findщоб повністю припинити пошук і після знаходження першого каталогу відповідності, то , що ви шукаєте -quit(починаючи з версії 4.2.3про GNU find). Це трохи складніше у використанні, оскільки він робить findвихід негайно - тому його -quitпотрібно розмістити в самому кінці команди:
find . -type d -name somename -exec ... -quit
Щоб це працювало як очікувалося, треба переконатися, що -execповернення справжнє (іншими словами, нульовий статус). Якщо ви хочете -execігнорувати статус виходу , щоб це -quitзавжди працювало, вам потрібна невелика хитрість:
find . -type d -name somename \( -exec ... -o -true \) -quit
або
find . -type d -name somename \( -exec ... -o -quit \)
або
find . -type d -name somename \( -exec ... , -quit \) # a comma before -quit
Найголовніше, як findпрацює, - це те, що всі дії ("тести") трактуються як логічні предикати, інтерпретовані зліва направо. Тому остання дія (наприклад -quit) буде виконана лише в тому випадку, якщо вся попередня частина не повернула помилкового . За замовчуванням усі тести поєднуються з логічним "AND", -oопція змінює суглоб на "OR".
Складний елемент -o, який findможе "оптимізувати" вашу команду, а не запускати -execчастину, якщо ви просто введете
find . -type d -name somename -exec ... -o -quit
Щоб впоратися з цим, ви можете змусити findоцінити всі предикати, об'єднані з "АБО", додавши їх у круглі дужки.