Eu tenho 3 diretórios no caminho atual.
$ls
a_0db_data a_clean_0db_data a_clean_data
$ls a_*_data
a_0db_data:
a_clean_0db_data:
a_clean_data:
$ls a_[a-z]*_data
a_clean_0db_data:
a_clean_data:
Eu esperava que o último comando ls correspondesse apenas a_clean_data
. Por que ele também coincide com o que contém 0
?
bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
bash
regular-expression
wildcards
user13107
fonte
fonte
a_*_data
corresponder a algum desses arquivos não o surpreendeu?Respostas:
A
[a-z]
parte não é o que corresponde ao número; é o*
. Você pode estar confundindo globbing de shell e expressões regulares .Ferramentas como
grep
aceitam vários tipos de expressões regulares ( básicas por padrão,-E
para estendidas,-P
para expressões regulares Perl )Por exemplo (
-v
inverte a partida)Se você deseja usar uma regex bash, aqui está um exemplo de como testar se a variável
$ref
é um número inteiro:fonte
Então o problema é: por que
a_[a-z]*_data
combinaa_clean_0db_data
?Isso pode ser dividido em quatro partes:
a_
coincide com o início dea_clean_0db_data
, deixandoclean_0db_data
para ser correspondido[a-z]
corresponde a qualquer caractere no intervaloa-z
(por exemploc
), deixandolean_0db_data
a correspondência*
corresponde a qualquer número de caracteres, por exemplolean_0db
_data
corresponde ao final_data
Em expressões regulares,
[a-z]*
significaria qualquer número de caracteres (incluindo zero) no intervalo de a..z , mas você está lidando com globbing de shell, não com expressões regulares.Se você deseja expressões regulares, algumas
find
implementações têm um-regex
predicado para isso:O
-maxdepth
é aqui apenas para limitar os de resultados de pesquisa para a pasta em que está. A expressão regular corresponde a toda filename, portanto, eu adicionei um^.*/
para corresponder ao caminho-partefonte
*
em padrões de shell corresponde a 0 ou mais caracteres. Não deve ser confundido com o*
operador de expressão regular que significa 0 ou mais do átomo anterior .Não há equivalente a regexp
*
nos padrões básicos de shell. No entanto, várias conchas têm extensões para isso.ksh
tem*(something)
:você pode ter o mesmo
bash
comshopt -s extglob
ouzsh
comsetopt kshglob
:Em
zsh
comextendedglob
habilitado,#
é equivalente à expressão regular*
:Nas versões recentes de
ksh93
, você também pode usar expressões regulares em globs. Aqui com expressões regulares estendidas :Observe que
[a-z]
corresponde a coisas diferentes, dependendo da localidade atual. Ele geralmente corresponde apenas a 26a
paraz
letras não acentuadas latinos naC
localidade. Em outros locais, geralmente corresponde a mais e nem sempre faz sentido. Para corresponder uma letra em sua localidade, você pode preferir[[:alpha:]]
.fonte
[a-z]
correspondência mais que as 26 letras correspondentes no código C? O que me lembro de quando olhei pela última vez isso, todas as codificações praticamente usadas nas variantes do Unix tinham a ISO-646 como base (então os 128 códigos superiores eram usados de maneira diferente, diretamente para caracteres em codificações como a ISO-8859-X, combinados em codificações como UTF-8 ou a família EUC). Mesmo o AIX não possuía localidades EBCDIC (pelo menos, disponíveis para mim). Lembro-me de tentar descobrir se os padrões POSIX / UNIX exigiam, mas não lembro o resultado.[a-z]
geralmente incluié
ouí
(mas não necessariamenteź
) nos locais onde o conjunto de caracteres os possui, se o ponto de código nessa codificação está entre o de a e z ou não. Somente o código de idioma C garante uma ordem de classificação com base no valor do ponto de código. Veja esta outra resposta para mais detalhes.