¿Hay alguna manera de combinar lógicamente dos comandos de shell que se invocan con find - exec ?
Por ejemplo, para imprimir todos los archivos .csv que contienen la cadena foo junto con su aparición, me gustaría hacer:
find . -iname \*.csv -exec grep foo {} && echo {} \;
pero bash se queja con "argumento perdido para '-exec'"

-execen secuencia o usar uno solo-exec sh -c 'grep foo "$0" && printf %s\\n "$0"' {} \;.sh(en este caso{}) sea$1y$0sea algo asísh. Pero, de hecho, tienes razón, el primer argumento aparece como$0. Tener el primer argumento como el nombre del comando de invocación es solo una convención, que no se aplica automáticamente en estos casos.Respuestas:
-execes un predicado que ejecuta un comando (no un shell) y se evalúa como verdadero o falso en función del resultado del comando (estado de salida cero o no cero).Asi que:
sería imprimir la ruta del archivo, si
greplos hallazgos de Foo en el archivo. En lugar de-printque pueda usar otro-execpredicado o cualquier otro predicadoVea también los operadores
!y-ofind para negación y or .Alternativamente, puede iniciar un shell como:
O para evitar tener que iniciar un shell para cada archivo:
fuente
El problema que enfrenta es que el shell primero analiza la línea de comando y ve dos comandos simples separados por el
&&operador:find . -iname \*.csv -exec grep foo {}yecho {} \;. Citando&&(find . -iname \*.csv -exec grep foo {} '&&' echo {} \;) no pasa por eso, pero ahora el comando ejecutado porfindalgo así comogrepcon los argumentosfoo,wibble.csv,&&,echoywibble.csv. Debe indicarlefindque ejecute un shell que interpretará al&&operador:Tenga en cuenta que el primer argumento después
sh -c SOMECOMMANDes$0, no$1.Puede guardar el tiempo de inicio de un proceso de shell para cada archivo agrupando las invocaciones de comando con
-exec … +. Para facilitar el procesamiento, pase un valor ficticio$0para"$@"enumerar los nombres de archivo.Si el comando de shell solo tiene dos programas separados
&&,findpuede hacer el trabajo por sí mismo: escriba dos-execacciones consecutivas , y la segunda solo se ejecutará si la primera sale con el estado 0.(Supongo que
grepyechoson solo para fines ilustrativos, ya que-exec echopueden reemplazarse-printy el resultado resultante no es particularmente útil de todos modos).fuente
./some-file: grep: command not foundmensaje de error confuso .-exec find sh -c '... "$1"' sh {} \;No tendría el problema. Hay un error tipográfico (relacionado) en su segundo comando de búsqueda.En este caso específico, haría:
find . -iname \*.csv -exec grep -l foo \{\} \;O si tienes ack :
ack -al -G '.*\.csv' fooPara responder a su pregunta real, algo como esto puede funcionar:
find . -iname \*.csv -exec sh -c "grep foo {} && echo {}" \;fuente