[A-Z]
não significa letras maiúsculas. Isso significa letras de A
a Z
, que podem incluir letras minúsculas. Normalmente você deve usar [[:upper:]]
. (Isso funciona no Bash mesmo sem extglob
.)
Quais caracteres [A-Z]
correspondem à sua localidade.
Você esclareceu que você deseja mostrar todos os nomes de arquivos que contenham pelo menos caracteres maiúsculos em qualquer lugar - não apenas nomes de arquivos consistindo inteiramente de letras maiúsculas - mas que quando você usa ls *[A-Z]*
, você obtém alguns nomes de arquivos que não têm nenhum caracteres maiúsculos neles.
Isso acontece quando a ordenação lexicográfica do seu código do idioma interpõe letras maiúsculas e minúsculas (por exemplo, AaBbCcDd ...). Embora você possa definir outro local (por exemplo, LC_ALL=C
), a melhor solução é escrever um padrão que corresponda especificamente às letras maiúsculas.
Quais caracteres são letras maiúsculas também podem variar entre as localidades, mas presumivelmente se algo for uma letra maiúscula na sua localidade, você deseja incluí-la. Então, isso é provavelmente uma vantagem de [[:upper:]]
em vez de uma desvantagem.
Use [[:upper:]]
.
A maioria dos shells no estilo Bourne, como o Bash, suporta classes de caracteres POSIX em globs. Este comando listará as entradas em /etc
cujos nomes têm pelo menos uma letra maiúscula:
ls -d /etc/*[[:upper:]]*
Algumas das entradas que você recebe podem ser diretórios. Se você deseja mostrar seu conteúdo em vez de apenas listar os diretórios, você pode remover o sinalizador -d
. Você também pode colocar um sinalizador --
antes do padrão, caso tenha entradas em /etc
que começam com -
. Você provavelmente não, no entanto. (Em um script, você geralmente desejará usar --
aqui.)
Você provavelmente não quer dotfiles, mas se você quiser ...
Isso não mostrará entradas que começam com .
. Normalmente você não quer mostrá-los. Se você quiser, a maioria dos shells permite que você escreva um único glob que também os corresponda ou configure o globbing para incluí-los por padrão. A opção de incluir automaticamente as entradas de lead- .
no Bash é dotglob
e pode ser ativada com shopt -s dotglob
. Para outras granadas, consulte
. Ou você pode simplesmente escrever uma segunda glob para eles:
ls -d /etc/*[[:upper:]]* /etc/.*[[:upper:]]*
As cascas de estilo Bourne mais populares suportam expansões de chaves, para que você possa escrever isso mais compactamente com menos repetição:
ls -d /etc/{,.}*[[:upper:]]*
Na maioria dos shells, incluindo Bash, quando você escreve dois globs separados, você recebe uma mensagem de erro quando um deles não expande - porque o comportamento padrão na maioria dos shells é passá-lo não expandido. Mas ls
ainda mostrará as entradas que corresponderam à outra. Mas como Stéphane Chazelas apontou , em alguns shells, incluindo o muito popular Zsh, todo o comando falha e ls
nunca é executado. Se você estiver usando o shell interativamente, isso não é realmente prejudicial, porque você pode modificar o comando executá-lo novamente, mas essas construções são inadequadas para scripts portáteis. O Bash também se comportará dessa maneira se você definir a opção failglob
shell.
Você não precisa de ampliação para isso.
No Bash, você não precisa ter o globbing estendido ativado para usar classes de caracteres POSIX em padrões glob. No meu sistema com o Bash 4.3.48:
ek@Io:~$ shopt extglob
extglob off
ek@Io:~$ ls -d /etc/*[[:upper:]]*
/etc/ConsoleKit /etc/LatexMk /etc/ODBCDataSources /etc/UPower
/etc/ImageMagick-6 /etc/NetworkManager /etc/rcS.d /etc/X11
Mas é necessário que você corresponda a nomes de arquivos de somente letras maiúsculas.
O que você faz precisa de globalização estendida é se você deseja combinar nomes de arquivos consistindo somente de letras maiúsculas. Então você usaria +([[:upper:]])
ou *([[:upper:]])
, e esses são globs estendidos.
Se você estiver usando o Bash, consulte este artigo , este guia , 3.5.8.1 Combinação de padrões no manual do GNU Bash para detalhes. Veja também a resposta de Stéphane Chazelas .