Encuentre archivos de diferentes directorios con inclusión y exclusión de algunos

Encuentre archivos de diferentes directorios con inclusión y exclusión de algunos

Quiero buscar archivos de tres carpetas diferentes con ciertos archivos incluidos y excluidos.
Carpeta 1:

  • Ruta: /var/www/app/var/log/
  • Excluir solo: file1.log y file2.log

Carpeta 2:

  • Ruta: /var/log/web/log/
  • Incluir sólo: error.log

Carpeta 3:

  • Ruta: /var/log/service/log/
  • Incluir solo: app1.error.log y app2.error.log

¿Cómo buscaría archivos de tres carpetas diferentes en este caso?

Respuesta1

Puedes hacer esto con find. Lea sobre el uso general de finden el contexto de excluir e incluir:Buscar archivos de forma recursiva con exclusiones e inclusiones..

Su problema implica tres caminos y requisitos diferentes para cada uno. Se pueden especificar muchos puntos de partida en una única invocación de findy construir una expresión (por ejemplo, con -path) de modo que se realicen diferentes pruebas para diferentes rutas. Es posible pero bastante engorroso. Una forma sencilla es ejecutar tres comandos de búsqueda separados en secuencia.

find /var/www/app/var/log ! -name file1.log         ! -name file2.log
find /var/log/web/log       -name error.log
find /var/log/service/log   -name app1.error.log -o   -name app2.error.log

Notas:

  • Los espacios múltiples en los comandos anteriores son solo para enfatizar su estructura y similitudes.

  • Dices "Quiero buscar archivos". Los comandos anteriores encontraránarchivosincluyendo archivos del tipo directorio; en particular, el primer comando encontrará su propio punto de partida ( …/log). Para buscar archivos normales sólo necesitas -type f. Para buscar archivos que no sean directorios solo necesita ! -type d.

  • Si file1.logo app1.error.loges del tipo directorio, entonces no está claro si "incluido" o "excluido" se refiere solo al directorio o al directorio y todo lo que se encuentra debajo. Probablemente esto no sea un problema porque lo más probable file1.loges que sean archivos normales en su configuración.

    Para que conste, cada uno de los comandos anteriores atraviesa todo el árbol de directorios desde su punto de partida. Por ejemplo, si file1.loges del tipo directorio, ! -name file1.logno dejará findde realizar pruebas file1.log/foo. Para excluir un subárbol necesita -prune.

  • findfunciona de forma recursiva. La forma más sencilla de hacer que GNU findno descienda a subdirectorios es -maxdepth 1. Es posible que las implementaciones que no sean GNU no lo admitan. Con puramente POSIXfind No es tan simple.

    tu etiquetaste; Ubuntu proporciona GNU findlisto para usar, así que úselo -maxdepth 1libremente.

  • uso adecuado de-o no es tan sencillo como desearías.

  • Si hay enlaces simbólicos involucrados, lea sobre las opciones -Hy -Len man 1 find. Es posible que desee utilizar uno de ellos.


Con todo esto en mente, puedo crear una variante de ejemplo del tercer comando quetal vezSe adapta mejor a tus necesidades:

find /var/log/service/log/ -maxdepth 1 -type f \( -name app1.error.log -o -name app2.error.log \)

O POSIX-ly (para que la respuesta sea más útil para una audiencia general):

find /var/log/service/log/. \( -name . -o -prune \) -type f \( -name app1.error.log -o -name app2.error.log \)

El último componente del punto de partida en el último comando termina es .. Esto nos permite utilizar una solución genérica (quiero decir que la forma -name . -o -pruneno depende de la parte realmente significativa de la ruta del punto de partida). Por otro lado, findse incluirá /.en cada nombre de ruta, es posible que no desee esto.


Ejecutar tres findmensajes en lugar de uno no le impide enviar los resultados a un único destino (por ejemplo xargs):

{ find … ; find … ; find … ; } | xargs …

Tenga en cuenta que en Ubuntu puede hacerlo find … -print0 | xargs -r0 …. Esto esmás robustoque find … -print | xargs …, aunque no es portátil.

información relacionada