Відповідь Муру підходить і добре підходить для випадків, коли ми хочемо щось надрукувати, якщо файл знайдений. У загальному випадку, коли ми хочемо виконати зовнішню команду, наприклад echo, ми можемо використовувати -execпрапор.
$ find . -name 'xac' -exec echo "I found " {} \; -quit
I found ./xac
{}Частина проходить ім'я файлу в команді між -execі в \;якості аргументів. Зверніть увагу на \попереднє ;- це заважає помилковій інтерпретації оболонки ; в крапці з комою, яка закривається оболонкою, означає кінець команди, але, коли вона переходить з косою косою, оболонка буде розглядати її як текст, що переноситься на findкоманду, і знаходить команду, яка служить для закриття -execаргументів прапора.
Для побудови умовних умов if found do this; else do thatподібного роду ми могли б використовувати підменю команд $()та testкоманду (ака [):
$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"
not found
$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"
found
Звертаючись до коментаря Дана
Ден у коментарях запитав:
Чи не відлуння "Я знайшов {}" краще, ніж відлуння "Я знайшов" {}? Можливо, для відлуння це добре, але якщо хтось скопіює команду та замінить ехо на іншу команду, у них можуть виникнути проблеми
Давайте розберемося спочатку з проблемою. Зазвичай в оболонках є поняття розділення слів, що означає, що нерозмінені змінні та позиційні параметри будуть розширені та розглядаються як окремі елементи. Наприклад, якщо у вас є змінна varі містить hello worldтекст, коли ви робите touch $varоболонка буде розбити його на два окремих пунктів helloі worldі touchбуде зрозуміло , що , як якщо б ви намагалися створити 2 окремі файли; якщо ви це зробите touch "$var", то оболонка буде розглядатись hello worldяк один блок, і touchстворить лише один файл. Це важливо, щоб зрозуміти, що це відбувається лише завдяки тому, як працюють снаряди.
Навпаки, findвід такої поведінки не страждає, оскільки команди обробляються самі findсобою і виконуються execvp()системним викликом, тому оболонки не задіяні. Хоча фігурні дужки мають особливе значення в оболонках, оскільки вони з'являються в середині findкоманди, а не на початку, вони не мають особливого значення для оболонки в цьому випадку. Ось приклад. Створимо кілька складних імен і спробуємо передати їх як аргумент statкоманді.
$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt
$ find -type f -exec stat -c "%F" {} \; -print
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt
Як бачите, отримання statскладних імен файлів ідеально добре find, що є однією з головних причин, чому його рекомендують використовувати в портативних сценаріях, і особливо корисно, коли ви переглядаєте дерево каталогів і хочете зробити щось із назви файлів, які потенційно можуть мати особливі символи в них. Тому не потрібно цитувати фігурні дужки для команд, виконаних у find.
Це вже інша історія, коли шкаралупа втягується. Іноді для обробки імені файлів потрібно використовувати оболонку. У цьому випадку цитування дійсно має значення, але важливо усвідомити, що це не проблема - це оболонка, яка робить розбиття слів.
$ find -type f -exec bash -c "stat {}" sh \;
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory
Тож коли ми цитуємо в оболонці , це спрацює. Але знову ж таки, це важливо для оболонки, а не find.
$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;
regular empty file
regular empty file
regular empty file
/some/pathрозповідає, з чого почати шукати, але нічого не говорить про те, що шукати. Те саме у вашій відповіді. Що для мене працюєfind /some/path -name xac -print0 -quit | grep -qz . && echo found. Я щось пропустив?