Correspondendo nome de arquivo de n letras com ls

Correspondendo nome de arquivo de n letras com ls

estou usando ols comando no bash, tentando encontrar todos os arquivos ou diretório de comprimento n. Digamos n = 5

Meu comando é:

ls ?????

Mas isso também incluiria caracteres que não são letras, como ponto final. Por exemplo, os seguintes arquivos corresponderiam:

ab.cd    
abd.c

Quero apenas combinar arquivos com nomes de 5 letras ou números:

five1
five2    
five3

Mas não

abc.d    
ab.cd    
a.bcd

Como posso modificar meu comando?

Resposta 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]

Encontrei a resposta, mas como posso tornar isso menos feio?

Responder1

Observe que não é lsisso que interpreta esses globos. Esses globs são expandidos pelo seu shell em uma lista de nomes de arquivos que são passados ​​como argumentos para ls. Diferentes shells têm diferentes capacidades de globbing. bashtem algumas extensões sobre globs padrão (emprestados ksh88e habilitados com shopt -s extglob), mas ainda é limitado em comparação com shells como zshouksh93 .

Com zsh:

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

ksh93:

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

ou:

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

ou, se você quiser usar expressões regulares estendidas:

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

Com bashou outros shells POSIX que não possuem operadores globbing equivalentes, você precisaria fazer:

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

Observe que isso [[:alnum:]]inclui qualquer caractere alfabético na localidade atual (não apenas alfabetos latinos e muito menos o inglês) e 0123456789(e possivelmente outros tipos de dígitos). Se você quiser as letras do alfabeto inglês, nomeie os caracteres individualmente:

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

Ou use a localidade C:

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

Responder2

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

Responder3

Se for usar lsda maneira que você mencionou, você deve usar o-d opção; caso contrário, ele listará osconteúdode qualquerdiretórios cujos nomes têm cinco letras e/ou dígitos, em vez de listar os próprios nomes. Além disso, você pode fazer

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

mas isso é exatamente o mesmo que a resposta que você tem agora.

Além disso, se você nãoprecisarpara usar lsem seu comando, você poderia usar

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

que listará todas as correspondências em uma linha, ou

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

que os listará em linhas separadas.

Responder4

Construa a expressão em uma variável:

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

Coloque-o em uma função para ser sofisticado/reutilizável:

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

 ls -ld $(alnumglob 5)

informação relacionada