¿encontrar nombres de archivo que NO terminen en extensiones específicas en Unix?


207

¿Hay una manera simple de encontrar recursivamente todos los archivos en una jerarquía de directorios que no terminen en una lista de extensiones? Por ejemplo, todos los archivos que no son * .dll o * .exe

UNIX / GNU find, por poderoso que sea, no parece tener un excludemodo (o me falta), y siempre me ha resultado difícil usar expresiones regulares para encontrar cosas que no coinciden con una expresión en particular .

Estoy en un entorno de Windows (usando el puerto GnuWin32 de la mayoría de las herramientas GNU), por lo que estoy igualmente abierto para soluciones exclusivas de Windows.

Respuestas:


343

O sin (y la necesidad de escapar de él:

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

66
-notpuede ser reemplazado por '!'(se recomienda cotizar). Por otro lado, -namees sensible a -inamemayúsculas y minúsculas.
Ivan Chau


8
$ find . -name \*.exe -o -name \*.dll -o -print

Las primeras dos opciones de nombre no tienen opción de impresión, por lo que se omitieron. Todo lo demás está impreso.


4

Podrías hacer algo usando el comando grep:

find . | grep -v '(dll|exe)$'

La -vbandera en grepsignifica específicamente "encuentra cosas que no coinciden con esta expresión".


66
grep -v '\. (dll | exe) $' evitaría la coincidencia de nuevo en un archivo o directorio llamado "dexe", por ejemplo
drAlberT

Esto solo funciona con expresiones regulares extendidas. Tuve que agregar -E (o usar egrep) para que esto funcione.
joctee

2

uno mas :-)

$ ls -ltr
total 10
-rw-r - r-- 1 scripter linuxdumb 47 dic 23 14:46 test1
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:40 test4
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:40 test3
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:40 test2
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:41 archivo5
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:41 archivo4
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:41 archivo3
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:41 archivo2
-rw-r - r-- 1 scripter linuxdumb 0 4 de enero 23:41 archivo1
$ encontrar. -tipo f! -nombre "* 1"! -name "* 2" -print
./test3
./test4
./file3
./file4
./file5
PS

Referencia de comando de búsqueda de Unix


1
find  /data1/batch/source/export   -type f -not  -name "*.dll" -not -name "*.exe"

1

Linux / OS X:

A partir del directorio actual, busque recursivamente todos los archivos que terminen en .dll o .exe

find . -type f | grep -P "\.dll$|\.exe$"

Comenzando desde el directorio actual, encuentre recursivamente 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 que se utilizarán junto con el comando grep . Con el propósito de exceder el comando grep en conjunto con expresiones regulares, encuentro que el estilo Perl es el estilo más poderoso.

(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 ".dll $" es un carácter de control delimitador que le dice al shell que la cadena del nombre de archivo termina con ".dll"


0

Otras soluciones en esta página no son deseables si tiene una larga lista de extensiones (mantener una secuencia larga -not -name 'this' -not -name 'that' -not -name 'other'sería tediosa y propensa a errores) o si la búsqueda es programática y la lista de extensiones está construida en tiempo de ejecución.

Para esas situaciones, findpuede ser deseable una solución que separe más claramente los datos (la lista de extensiones) y el código (los parámetros para ). Dado un directorio y una estructura de 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 OSX nativo find: utilice gnu find en su lugar.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.