Supongamos que quiero encontrar todos los archivos .txt y buscar alguna cadena. Yo haría:

find ./ -type f -name "*.txt" -exec egrep -iH "something" "{}" \; 

¿Qué pasa si quiero hacer un filtrado más complejo, como este?

egrep something file.txt | egrep somethingelse | egrep other 

Inside find -exec? (o similar)

Por favor, tenga en cuenta que estoy buscando una solución que pueda escribir fácilmente cuando la necesite. Sé que esto se podría hacer con unas pocas líneas usando un script de shell, pero eso no es lo que estoy buscando.

Responder

Si debe hacerlo desde dentro de buscar, debe llamar a un shell:

find ./ -type f -name "*.txt" -exec sh -c "grep -EiH something "$1" | grep -E somethingelse | grep -E other" sh {} \; 

Otras alternativas incluyen usar xargs en su lugar:

find ./ -type f -name "*.txt" | xargs -I{} grep -EiH something {} | grep -EiH somethingelse | grep -EiH other 

O , mucho más seguro para nombres de archivo arbitrarios (suponiendo que su find admita -print0):

find ./ -type f -name "*.txt" -print0 | xargs -0 grep -EiH something {} | grep -Ei somethingelse | grep -Ei other 

O bien, podría usar un ciclo de shell en su lugar:

find ./ -type f -name "*.txt" -print0 | while IFS= read -d "" file; do grep -Ei something "$file" | grep -Ei somethingelse | grep -Ei other done 

Comentarios

  • El primero es exactamente lo que estaba buscando. Extremadamente simple y lo suficientemente pequeño como para escribir según mis necesidades. Gracias.
  • … y xargs también podría usarse como xargs -I {} sh -c '...' sh {}, si uno quisiera (hace es posible ejecutar trabajos en paralelo con -P si se desea).

Responder

Editar: Esta respuesta no es la preferida, pero se deja aquí para comparar e ilustrar peligros potencialmente peligrosos en secuencias de comandos bash.


Puede poner bash (u otro shell) como su comando -exec:

 find -type -f -name "*.txt" -exec bash -c "egrep -iH something "{}" | egrep somethingelse | egrep other" \;  

Una de las desventajas de hacerlo de esta manera es que crea más potencial para problemas de citas anidadas a medida que sus comandos se vuelven más complejos. Si quieres evitar eso, puedes dividirlo en un for -loop:

 for i in $(find -type -f -name "*.txt"); do if egrep -iH something "$i" | egrep somethingelse | egrep other; then echo "Found something: $i" fi done  

Comentarios

  • El primero es exactamente lo que estaba buscando. Extremadamente simple y lo suficientemente pequeño como para escribir según mis necesidades. Gracias.
  • Ese bucle for es una muy mala idea. También conocido como bash pitfall # 1 .
  • Este "{}" en su primer comando puede incluso llevar a la inyección de código. Imagina que tienes archivos míos y hay ' un archivo llamado literalmente " & rm -rf ~ & : ".txt. Afortunadamente para usted, -type -f no es válido, acaba de guardar su directorio de inicio. Corrija el error tipográfico y vuelva a intentarlo. 🙂 terdon lo hizo bien: find … -exec sh -c '… "$1" …' foo {} \;.
  • ¡Gracias por la información! Sí, el -type -f es un error tipográfico que cometo constantemente cuando uso find, y no ' t lo noto en mi respuesta. ¡Ups! terdon ' La respuesta es mejor, pero ' dejaré esto para fines comparativos.
  • @terdon: tx para hacer referencia a la página mywiki.wooledge.org. Es ' agradable tener un montón de médicos de cabecera perfectamente resumidos en un solo lugar.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *