Encuentra nombres de archivos que no contienen una cadena especificada

19

Me gustaría ejecutar lo contrario de:

find . -name "*2013*"

Encuentra todos los archivos en el directorio actual que no contienen la cadena "2013" en sus nombres. ¿Cómo puedo hacer eso?

usuario1058398
fuente

Respuestas:

28

Simplemente:

find . ! -name '*2013*'

Agregue un ! -type dpara excluir también los archivos de tipo directorio (como él .mismo), o -type fpara incluir solo archivos normales , excluyendo todos los otros tipos de archivos (directorios, quince, enlaces simbólicos, dispositivos, sockets ...).

Sin embargo, tenga cuidado porque *coincide con una secuencia de 0 o más caracteres . Por lo tanto, podría informar los nombres de archivo que contienen 2013si eso 2013fue precedido o seguido por algo que no puede decodificarse completamente como caracteres válidos en la configuración regional actual.

Eso puede suceder si se encuentra en un entorno local donde los caracteres se pueden codificar en más de un byte (como en UTF-8) para nombres de archivos que están codificados en una codificación diferente. Por ejemplo, en un entorno local UTF-8, informaría un Stéphane2013archivo si éhubiera sido codificado en el conjunto de caracteres iso8859-15 (como el byte 0xe9).

Lo mejor sería asegurarse de que los nombres de los archivos estén codificados en el conjunto de caracteres de la configuración regional, pero si no puede garantizarlo, se debe ejecutar finduna solución alternativa en la configuración regional de C:

LC_ALL=C find . ! -name '*2013*'
Stéphane Chazelas
fuente
4

Los patrones de nombre de archivo Ksh son suficientes:

# files with 2013
ls -d -- *2013*

# files without 2013
ls -d -- !(*2013*)

Referencia

Si su shell es bash, debe ejecutar shopt -s extglobantes de poder usar este patrón (puede ponerlo en su .bashrc). Si su shell es zsh, debe ejecutarlo setopt ksh_glob(puede ponerlo en su .zshrc). Zsh también ofrece ls -d -- ^*2013*, lo que requiere un preliminar setopt extended_glob.

Dependiendo de lo que esté haciendo con estos nombres de archivo, lspuede no ser el comando correcto para usar. Para almacenarlos en una matriz

filenames=( !(*2013*) )
for f in "${filenames[@]}"; do ...; done
Glenn Jackman
fuente
44
Sin embargo, eso no se repite en los subdirectorios y omitirá los archivos de puntos (y lsdevolverá un mensaje de error si el patrón no coincide con ningún archivo). También tenga en cuenta que kshordenará la lista.
Stéphane Chazelas
-1

Encuentra todos los archivos en el directorio actual que no contiene una cadena determinada, aquí "2013":

find . ! -name "*2013*" -type f
usuario7194913
fuente
2
Esto es esencialmente lo mismo que unix.stackexchange.com/a/102614/117549 de hace 3 años, excepto que ha agregado "-f" que hace que esta sea una respuesta peor.
Jeff Schaller