Hacer coincidir el nombre de archivo de n letras con ls

Hacer coincidir el nombre de archivo de n letras con ls

Estoy usando el lscomando en bash, tratando de encontrar todos los archivos o directorios de longitud n. digamos n=5

Mi comando es:

ls ?????

Pero esto también incluiría caracteres que no sean letras, como el punto. Por ejemplo, los siguientes archivos coincidirían:

ab.cd    
abd.c

Solo quiero hacer coincidir archivos que tengan nombres de 5 letras o números:

five1
five2    
five3

Pero no

abc.d    
ab.cd    
a.bcd

¿Cómo puedo modificar mi comando?

Respuesta encontrada:

ls [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]

Encontré la respuesta, pero ¿cómo puedo hacer que esto sea menos feo?

Respuesta1

Tenga en cuenta que no es eso lslo que interpreta esos globos. Su shell expande esos globos en una lista de nombres de archivos que se pasa como argumentos a ls. Diferentes proyectiles tienen diferentes capacidades de globo. bashtiene algunas extensiones sobre los globos estándar (tomados prestados ksh88y habilitados con shopt -s extglob) pero aún es limitado en comparación con shells como zsho ksh93.

Con zsh:

setopt extendedglob
ls -d [[:alnum:]](#c5)

ksh93:

ls -d {5}([[:alnum:]])

o:

ls -d {5}(\w) # (\w includes underscore in addition to alnums)

o, si desea utilizar expresiones regulares extendidas:

ls -d ~(E)^[[:alnum:]]{5}$

Con bashu otros shells POSIX que no tengan operadores globales equivalentes, deberá hacer:

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

Tenga en cuenta que [[:alnum:]]incluye cualquier carácter alfabético en la configuración regional actual (no solo los alfabetos latinos y mucho menos el inglés) y 0123456789(y posiblemente otros tipos de dígitos). Si desea las letras del alfabeto inglés, nombre los caracteres individualmente:

c='[0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]'
unset -v IFS
ls -d $c$c$c$c$c

O use la configuración regional C:

(export LC_ALL=C
ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]])

Respuesta2

ls -q | grep -Ex '[[:alnum:]]{5}'

Respuesta3

Si vas a utilizar lsla forma que mencionaste, debes usar la -dopción; de lo contrario, enumerará elcontenidode cualquierdirectorios cuyos nombres tienen cinco letras y/o dígitos, en lugar de enumerar los nombres mismos. Además, puedes hacer

ls -d [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

pero eso es exactamente lo mismo que escribir la respuesta que tienes ahora.

Además, si no lo hacesnecesidadpara usar lsen tu comando, puedes usar

echo [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]]

que enumerará todas las coincidencias en una línea, o

printf "%s\n" [[:alnum:]][[:alnum:]][[:alnum:]][[:alnum:]][:alnum:]]

que los enumerará en líneas separadas.

Respuesta4

Construya la expresión en una variable:

 e=""; for m in $(seq 1 5); do e="$e[A-Za-z0-9]"; done

Ponlo en una función para que sea elegante/reutilizable:

 alnumglob() {
    local e=""
    for m in $(seq 1 $1) ; do e="$e[A-Za-z0-9]"; done
    echo "$e"
 }

 ls -ld $(alnumglob 5)

información relacionada