Проблема, з якою ви стикаєтеся, полягає в тому, що оболонка спочатку аналізує командний рядок і бачить дві прості команди, розділені &&оператором:, 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"' {} \;.