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 find
to coś grep
z argumentami foo
, wibble.csv
, &&
, echo
i wibble.csv
. Musisz poinstruować, find
aby 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 SOMECOMMAND
to $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ą, $0
aby "$@"
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 &&
, find
może wykonać zadanie samodzielnie: napisz dwie kolejne -exec
akcje, 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 grep
i echo
są tylko w celach ilustracyjnych, ponieważ -exec echo
można je zastąpić, -print
a wynikowy wynik i tak nie jest szczególnie użyteczny.)
-exec
w sekwencji lub użyć jednego-exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;
.