listar arquivos cujo nome atenda a 3 critérios diferentes

2

É possível conseguir o seguinte com um simples comando ls usando o bash. Lista todos os arquivos que começam com duas letras, têm um e no nome e terminam com 1 ou mais letra. Em caso afirmativo, qual é o comando e a globalização estendida precisa ser ativada?

    
por damiant 06.10.2017 / 13:42

1 resposta

5

ls não corresponde a nomes de arquivos (a menos que você queira considerar extensões do GNU como --include / --exclude ). São os globs de shell normalmente usados para isso.

ls -ld [[:alpha:]][[:alpha:]]*e*[[:alpha:]]

localizaria arquivos que correspondam a esses requisitos, mas perderia ee , por exemplo. Você poderia fazer:

zsh

Usando o operador AND NOT / EXCEPT ( ~ ) e NOT ( ^ ):

setopt extendedglob
ls -ld [[:alpha:]](#c2)*~^*e*~^*[[:alpha:]]

Ou usando os operadores de expressões regulares perl -like look ahead:

setopt rematchpcre
match() [[ $REPLY =~ '^(?=.*e)(?=.*[[:alpha:]]$)[[:alpha:]][[:alpha:]]' ]]
ls -ld *(+match)

ksh93

Usando & dentro de @(...) :

ls -ld @([[:alpha:]][[:alpha:]]*&*e*&*[[:alpha:]])

Mesmo com suas expressões regulares aumentadas (ativadas com ~(X:...) ):

ls -ld ~(X:[[:alpha:]][[:alpha:]].*&.*e.*&.*[[:alpha:]])

Ou usando operadores de look-ahead tipo perl:

ls -ld ~(P:(?=.*e)(?=.*[[:alpha:]]$)[[:alpha:]][[:alpha:]])*

bash

bash não tem operador AND , mas suporta um subconjunto de operadores de ksh quando a opção extglob está ativada, pelo que pode fazer coisas como:

shopt -s extglob
ls -ld @([[:alpha:]]?([[:alpha:]]*)e?(*[[:alpha:]])|e[[:alpha:]]?(*[[:alpha:]]))

@(x|y) (como zsh ' (x|y) ) é um operador OR . ?(x) é uma x opcional (como zsh ' (x|) ; @(x|) também funcionaria para isso em ksh / bash ).

Outro truque é usar o fato de que "A e B" é "não (não (A) ou não (B))" , e o subconjunto de Os ksh globs suportados por bash , por isso, incluem operadores não e ou para que você possa fazer:

ls -ld !(!([[:alpha:]][[:alpha:]]*)|!(*e*)|!(*[[:alpha:]]))

Esses também funcionam em ksh (todas as variantes, não há shopt ) de onde esses operadores vêm, em primeiro lugar.

Abordagens não baseadas em glob

com find :

find . ! -name . -prune -name '[[:alpha:]][[:alpha:]]*' \
                        -name '*e*' \
                        -name '*[[:alpha:]]' -exec ls -ld {} +

(cuidado, a lista de arquivos não será ordenada e os nomes de arquivos contendo bytes que não formam caracteres válidos serão excluídos; os nomes dos arquivos também serão prefixados com ./ ).

    
por 06.10.2017 / 14:28