command line - guia - ¿UNIX encuentra para encontrar nombres de archivos que NO terminan en extensiones específicas?
qgis manual (8)
¿Existe una forma simple de encontrar recursivamente todos los archivos en una jerarquía de directorios que no terminan en una lista de extensiones? Por ejemplo, todos los archivos que no son * .dll o * .exe
El hallazgo de UNIX / GNU, poderoso como es, no parece tener un modo de exclude
(o me lo estoy perdiendo), y siempre me ha resultado difícil usar expresiones regulares para encontrar cosas que no coinciden con un particular expresión.
Estoy en un entorno de Windows (usando el puerto GnuWin32 de la mayoría de las herramientas de GNU), por lo que estoy igualmente abierto para soluciones solo de Windows.
Linux / OS X:
A partir del directorio actual, recursivamente encuentre todos los archivos que terminan en .dll o .exe
find . -type f | grep -P "/.dll$|/.exe$"
A partir del directorio actual, busque de forma recursiva todos los archivos que NO terminen en .dll o .exe
find . -type f | grep -vP "/.dll$|/.exe$"
Notas:
(1) La opción P en grep indica que estamos usando el estilo Perl para escribir nuestras expresiones regulares para usar junto con el comando grep . Con el fin de ejecutar el comando grep junto con expresiones regulares, encuentro que el estilo Perl es el estilo más poderoso que existe.
(2) La opción v en grep indica al shell que excluya cualquier archivo que satisfaga la expresión regular
(3) El carácter $ al final de decir ".dell $" es un carácter de control de delimitador que le dice al intérprete de comandos que la cadena de nombre de archivo termina con ".dll"
O sin (
y la necesidad de escapar de ella:
find . -not -name "*.exe" -not -name "*.dll"
y también excluir la lista de directorios
find . -not -name "*.exe" -not -name "*.dll" -not -type d
o en lógica positiva ;-)
find . -not -name "*.exe" -not -name "*.dll" -type f
Otras soluciones en esta página no son deseables si tiene una larga lista de extensiones: mantener una secuencia larga de -not -name ''this'' -not -name ''that'' -not -name ''other''
sería tedioso y el error -prone - o si la búsqueda es programática y la lista de extensiones se genera en tiempo de ejecución.
Para esas situaciones, una solución que separa más claramente los datos (la lista de extensiones) y el código (los parámetros a find
) puede ser deseable. Dada una estructura de directorios y archivos que se ve así:
.
└── a
├── 1.txt
├── 15.xml
├── 8.dll
├── b
│ ├── 16.xml
│ ├── 2.txt
│ ├── 9.dll
│ └── c
│ ├── 10.dll
│ ├── 17.xml
│ └── 3.txt
├── d
│ ├── 11.dll
│ ├── 18.xml
│ ├── 4.txt
│ └── e
│ ├── 12.dll
│ ├── 19.xml
│ └── 5.txt
└── f
├── 13.dll
├── 20.xml
├── 6.txt
└── g
├── 14.dll
├── 21.xml
└── 7.txt
Puedes hacer algo como esto:
## data section, list undesired extensions here
declare -a _BADEXT=(xml dll)
## code section, this never changes
BADEXT="$( IFS="|" ; echo "${_BADEXT[*]}" | sed ''s/|///|/g'' )"
find . -type f ! -regex ".*/./($BADEXT/)"
Lo que resulta en:
./a/1.txt
./a/b/2.txt
./a/b/c/3.txt
./a/d/4.txt
./a/d/e/5.txt
./a/f/6.txt
./a/f/g/7.txt
Puede cambiar la lista de extensiones sin cambiar el bloque de código.
NOTA no funciona con el find
nativo de OSX - use gnu find en su lugar.
Puedes hacer algo con el comando grep:
find . | grep -v ''(dll|exe)$''
El -v
en grep
significa específicamente "encontrar elementos que no coinciden con esta expresión".
uno mas :-)
$ ls -ltr total 10 -rw-r--r-- 1 scripter linuxdumb 47 Dec 23 14:46 test1 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:40 test4 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:40 test3 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:40 test2 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file5 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file4 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file3 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file2 -rw-r--r-- 1 scripter linuxdumb 0 Jan 4 23:41 file1 $ find . -type f ! -name "*1" ! -name "*2" -print ./test3 ./test4 ./file3 ./file4 ./file5 $
$ find . -name /*.exe -o -name /*.dll -o -print
Las primeras opciones de dos nombres no tienen opción de impresión, por lo que se omiten. Todo lo demás está impreso.
find /data1/batch/source/export -type f -not -name "*.dll" -not -name "*.exe"
find . ! /( -name "*.exe" -o -name "*.dll" /)