Problem, przed którym stoisz, polega na tym, że powłoka najpierw analizuje wiersz poleceń i widzi dwa proste polecenia oddzielone przez &&operatora: find . -iname \*.csv -exec grep foo {}i echo {} \;. Cytując &&( find . -iname \*.csv -exec grep foo {} '&&' echo {} \;) omija, ale teraz komenda wykonywana przez findto coś grepz argumentami foo, wibble.csv, &&, echoi wibble.csv. Musisz poinstruować, findaby uruchomić powłokę, która zinterpretuje &&operatora:
find . -iname \*.csv -exec sh -c 'grep foo "$0" && echo "$0"' {} \;
Zauważ, że pierwszy argument po sh -c SOMECOMMANDto $0, nie $1.
Możesz zaoszczędzić czas uruchamiania procesu powłoki dla każdego pliku, grupując wywołania poleceń -exec … +. Aby ułatwić przetwarzanie, podaj pewną wartość zastępczą, $0aby "$@"wyliczała nazwy plików.
find . -iname \*.csv -exec sh -c 'for x in "$@"; do grep foo "$x" && echo "$x"; done' \ {} +
Jeśli polecenie powłoki dzieli tylko dwa programy &&, findmoże wykonać zadanie samodzielnie: napisz dwie kolejne -execakcje, a druga zostanie wykonana tylko wtedy, gdy pierwsza zakończy pracę ze statusem 0.
find . -iname \*.csv -exec grep foo {} \; -exec echo {} \;
(Zakładam, że grepi echosą tylko w celach ilustracyjnych, ponieważ -exec echomożna je zastąpić, -printa wynikowy wynik i tak nie jest szczególnie użyteczny.)
-execw sekwencji lub użyć jednego-exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;.