Evitando un directorio al usar el comando find

En UNIX el comando find es uno de los más usados cuando de buscar un archivo en un árbol de directorios se trata. Su capacidad de búsqueda tiene la particularidad de poder ser usada para ejecutar acciones sobre cada uno de sus resultados mediante la opción -exec. Aunque no es muy común, hay ocaciones en que su capacidad de búsqueda la queremos limitar para excluir algunos directorios.

El comando find cuenta con la opción -prune; sin embargo su funcionamiento o utilización puede resultar algo obscura. Personalmente no he podido comprobar los resultados que se supone deberían obtenerse. Por ejemplo, imaginemos que deseáremos eliminar todos los archivos de extensión .log que pudieran encontrarse bajo cierta ruta. El comando


find . -name "*.log" -exec rm {} \; 2>/dev/null

debría lograrlo. Ahora consideremos quisieramos excluir de la eliminación los archivos que estuvieran en cierta ruta, de acuerdo con lo que la documentación de find indica, el siguiente comando debería hacerlo:


find . -name "*.log" -path ruta -prune -exec rm {} \; 2>/dev/null

Antes de ejecutar este comando, debe considerarse que, fuera de cualquier error de sintaxis, de funcionar bien o mal igualmente se trata de algo de única vez, ya que el efecto de un rm no puede ser revertido, por lo que en estos casos conviene primero validar el efecto de la búsqueda de una forma no destructiva. Esto puede lograrse de la siguiente forma:


[equipo] /opt/otro/sistema : > echo $SHELL
/usr/bin/sh
[equipo] /opt/otro/sistema : > uname -a
HP-UX equipo B.11.00 A 9000/800 159474646 two-user license
[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -exec echo {} \; 2>/dev/null
/opt/mi/applic/logs/1.log
/opt/mi/applic/logs/2.log
/opt/mi/applic/log/envia.log
/opt/mi/applic/005/log/c719005.log
/opt/mi/applic/040/graficas/transfiereImagen.log
/opt/mi/applic/var/log/C719_clima.log
/opt/mi/applic/var/log/C719_biva.log
/opt/mi/applic/var/log/C719003.log
/opt/mi/applic/ShellsGeneratorFiles/envia.log
/opt/mi/applic/repositorio/log/c719.000.pce.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell02.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell03.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell05.log
/opt/mi/applic/002/fls/2.0/log/c719.002.fls.log
[equipo] /opt/otro/sistema : >

Aquí lo que podemos observar es el resultado de la busqueda en una ruta desde otra diferente para todos los archivos con extensión .log. Ahora supongamos que los archivos que estan en /opt/mi/applic/logs deberían conservarse. Echando mano de -prune, en lo que parece ser la forma más natural no devuelve nada


[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -path /opt/mi/applic/logs -prune -exec echo {} \; 2>/dev/null
[equipo] /opt/otro/sistema : >

y la negación de la opción parece tampoco tener el efecto deseado (aunque es correcto en comparación a lo que se obtuvo sin negar la opción):


[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" ! -path /opt/mi/applic/logs -prune -exec echo {} \; 2>/dev/null
/opt/mi/applic/logs/1.log
/opt/mi/applic/logs/2.log
/opt/mi/applic/log/envia.log
/opt/mi/applic/005/log/c719005.log
/opt/mi/applic/040/graficas/transfiereImagen.log
/opt/mi/applic/var/log/C719_clima.log
/opt/mi/applic/var/log/C719_biva.log
/opt/mi/applic/var/log/C719003.log
/opt/mi/applic/ShellsGeneratorFiles/envia.log
/opt/mi/applic/repositorio/log/c719.000.pce.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell02.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell03.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell05.log
/opt/mi/applic/002/fls/2.0/log/c719.002.fls.log
[equipo] /opt/otro/sistema : >

Variaciones sobre el comando no parecen funcionar mas curiosamente la eliminacioón de la opción -prune y la adición de un operador lógico logran el efecto buscado:


[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -a ! -path "/opt/mi/applic/logs/*.log" -exec echo {} \; 2>/dev/null
/opt/mi/applic/log/envia.log
/opt/mi/applic/005/log/c719005.log
/opt/mi/applic/040/graficas/transfiereImagen.log
/opt/mi/applic/var/log/C719_clima.log
/opt/mi/applic/var/log/C719_biva.log
/opt/mi/applic/var/log/C719003.log
/opt/mi/applic/ShellsGeneratorFiles/envia.log
/opt/mi/applic/repositorio/log/c719.000.pce.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell02.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell03.log
/opt/mi/applic/repositorio/log/c719.000.pce.shell05.log
/opt/mi/applic/002/fls/2.0/log/c719.002.fls.log
[equipo] /opt/otro/sistema : >

Antes de dar por buena una inspección visual, conviene una validación cuantitativa, lo que se puede obtener fácilmente entubando la salida para ser usada con el comando wc. Así podemos verificar que el número de resltados con la solución inlcuye dos archivos que visualmente hemos visto son los que están en la ruta que deseamos evitar y nada menos.


[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -exec echo {} \; 2>/dev/null | wc -l
14
[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -a ! -path "/opt/mi/applic/logs/*.log" -exec echo {} \;
2>/dev/null | wc -l
12
[equipo] /opt/otro/sistema : >

Finalmente el comando a usar queda


[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -a ! -path "/opt/mi/applic/logs/*.log" -exec rm {} \; 2>/dev/null
[equipo] /opt/otro/sistema : >

y podemos comprobar sus resultados con el find que usamos en un inicio.


[equipo] /opt/otro/sistema : > find /opt/mi/applic -name "*.log" -exec echo {} \; 2>/dev/null
/opt/mi/applic/logs/1.log
/opt/mi/applic/logs/2.log
[equipo] /opt/otro/sistema : >

Anuncios

Un comentario en “Evitando un directorio al usar el comando find

  1. Muy buena información sobre el comando find, sobre todo está dirigida de una forma muy completa para que todos los interesados puedan obtener una solución sustentable y significativa para su uso.

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.