Проблема, з якою ви стикаєтеся, полягає в тому, що оболонка спочатку аналізує командний рядок і бачить дві прості команди, розділені &&
оператором:, find . -iname \*.csv -exec grep foo {}
і echo {} \;
. Цитування &&
( find . -iname \*.csv -exec grep foo {} '&&' echo {} \;
) обходить, але тепер команда виконується find
що - щось на зразок grep
з аргументами foo
, wibble.csv
, &&
, echo
і wibble.csv
. Вам потрібно доручити find
запустити оболонку, яка буде інтерпретувати &&
оператора:
find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;
Зауважте, що перший аргумент після sh -c SOMECOMMAND
є $0
, ні $1
.
Ви можете зберегти час запуску процесу оболонки для кожного файлу, згрупувавши виклики команд за допомогою -exec … +
. Для зручності обробки передайте деяке фіктивне значення таким $0
чином, щоб "$@"
перерахувати назви файлів.
find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +
Якщо команда оболонки є лише двома програмами, розділеними &&
, find
можна виконати завдання самостійно: записати дві послідовні -exec
дії, а друга виконуватиметься лише в тому випадку, якщо перша закінчується зі статусом 0.
find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;
(Я вважаю , що grep
і echo
призначений тільки для ілюстрації, так як -exec echo
може бути замінений , -print
і отриманий вихід не дуже корисно в будь-якому випадку.)
-exec
послідовно або використовувати один-exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;
.