
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 find
en 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 find
y 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.log
oapp1.error.log
es 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 probablefile1.log
es 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.log
es del tipo directorio,! -name file1.log
no dejaráfind
de realizar pruebasfile1.log/foo
. Para excluir un subárbol necesita-prune
.find
funciona de forma recursiva. La forma más sencilla de hacer que GNUfind
no 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 etiquetasteubuntu; Ubuntu proporciona GNU
find
listo para usar, así que úselo-maxdepth 1
libremente.uso adecuado de
-o
no es tan sencillo como desearías.Si hay enlaces simbólicos involucrados, lea sobre las opciones
-H
y-L
enman 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 -prune
no depende de la parte realmente significativa de la ruta del punto de partida). Por otro lado, find
se incluirá /.
en cada nombre de ruta, es posible que no desee esto.
Ejecutar tres find
mensajes 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.