find -exec con múltiples comandos

Estoy intentando usar find -exec con múltiples comandos sin ningún éxito. ¿Alguien sabe si comandos como los siguientes son posibles?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \; 

Básicamente, estoy tratando de imprimir la última línea de cada archivo txt en el directorio actual e imprimir al final de la línea, una coma seguida del nombre del archivo.

find acepta porciones de -exec múltiples para el comando. Por ejemplo:

 find . -name "*.txt" -exec echo {} \; -exec grep banana {} \; 

Tenga en cuenta que en este caso el segundo comando solo se ejecutará si el primero regresa con éxito, como lo menciona @Caleb. Si desea que ambos comandos se ejecuten independientemente de su éxito o falla, puede usar esta construcción:

 find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \; 
 find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \; 

Uno de los siguientes:

 find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \; find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \; find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \; 

Hay una manera más fácil:

 find ... | while read -r file; do echo "look at my $file, my $file is amazing"; done 

Alternativamente:

 while read -r file; do echo "look at my $file, my $file is amazing"; done <<< "$(find ...)" 

Otra forma es así:

 multiple_cmd() { tail -n1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \; 

en una línea

 multiple_cmd() { tail -1 $1; ls $1 }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \; 
  • multiple_cmd() ” – es una función
  • export -f multiple_cmd ” – lo exportará para que cualquier otra subshell pueda verlo
  • find *.txt -exec bash -c 'multiple_cmd "$0"' {} \; ” – encuentra que ejecutará la función en tu ejemplo

De esta forma, multiple_cmd puede ser tan largo y tan complejo como lo necesite.

Espero que esto ayude.

No sé si puede hacer esto con find, pero una solución alternativa sería crear un script de shell y ejecutar esto con find.

lastline.sh:

 echo $(tail -1 $1),$1 

Hacer el script ejecutable

 chmod +x lastline.sh 

Use find :

 find . -name "*.txt" -exec ./lastline.sh {} \; 

La primera respuesta de Denis es la respuesta para resolver el problema. Pero, de hecho, ya no es un hallazgo con varios comandos en un solo ejecutivo como sugiere el título. Para responder al único ejecutivo con varios comandos, tendremos que buscar otra cosa para resolverlo. Aquí hay un ejemplo:

Mantenga las últimas 10000 líneas de archivos .log que se han modificado en los últimos 7 días usando 1 comando exec usando varias {} referencias

1) vea qué hará el comando en qué archivos:

 find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \; 

2) Hazlo: (nota no más “\>” pero solo “>” esto es deseado)

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;

Gracias a Camilo Martin, pude responder una pregunta relacionada:

Lo que quería hacer era

 find ... -exec zcat {} | wc -l \; 

que no funcionó. Sin embargo,

 find ... | while read -r file; do echo "$file: `zcat $file | wc -l`"; done 

funciona, así que ¡gracias!

debería usar xargs 🙂

 find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT 

otro (trabajando en osx)

 find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'