Я хочу знайти всі каталоги з певним рядком, щоб я міг ще раз знайти файли, що містяться в ньому.
Тому я не хочу витрачати час на ./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
оцінити всі предикати, об'єднані з "АБО", додавши їх у круглі дужки.