O problema que você está enfrentando é que o shell analisa primeiro a linha de comando e vê dois comandos simples separados pelo &&operador:, find . -iname \*.csv -exec grep foo {}e echo {} \;. Citando &&( find . -iname \*.csv -exec grep foo {} '&&' echo {} \;) ignora isso, mas agora o comando executado por findalgo como grepcom os argumentos foo, wibble.csv, &&, echoe wibble.csv. Você precisa instruir findpara executar um shell que interpretará o &&operador:
find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;
Observe que o primeiro argumento a seguir sh -c SOMECOMMANDé $0não $1.
Você pode economizar o tempo de inicialização de um processo de shell para cada arquivo agrupando as chamadas de comando -exec … +. Para facilitar o processamento, passe algum valor fictício $0para "$@"enumerar os nomes dos arquivos.
find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +
Se o comando shell tiver apenas dois programas separados por &&, ele findpoderá -execexecutar o trabalho sozinho: escreva duas ações consecutivas e a segunda será executada apenas se a primeira sair com o status 0.
find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;
(Presumo que grepe echosão apenas para fins de ilustração, como -exec echopode ser substituído por -printe a saída resultante não é particularmente qualquer maneira útil.)
-execem sequência ou usar um único-exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;.