Você leu o manual do bash? O que você acha incerto?
icarus 27/01
3
Pesquise na página do manual do bash = =
Jeff Schaller
Respostas:
46
Na ~verdade, é parte do operador =~que executa uma correspondência de expressão regular da string à sua esquerda e a expressão regular estendida à sua direita.
[["string"=~ pattern ]]
Observe que a string deve ser citada e que a expressão regular não deve ser citada.
Um operador semelhante é usado na linguagem de programação Perl.
As expressões regulares entendidas por bashsão as mesmas que o GNU grepentende com a -Eflag, ou seja, o conjunto estendido de expressões regulares.
Um pouco fora de tópico, mas é bom saber:
Ao fazer a correspondência com uma expressão regular que contém grupos de captura, a parte da sequência capturada por cada grupo está disponível na BASH_REMATCHmatriz. O zeroth / primeira entrada em Isto corresponde matriz para &no padrão de substituição sedde comando de substituição (ou $&em Perl), que é o bit da cadeia que corresponde ao padrão, enquanto as entradas no índice 1 e seguintes corresponde a \1, \2, etc. . em um sedpadrão de substituição (ou $1, $2etc, em Perl), isto é, os bits correspondentes por cada parêntese.
Exemplo:
string=$( date +%T )if[["$string"=~^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]];then
printf 'Got %s, %s and %s\n' \
"${BASH_REMATCH[1]}""${BASH_REMATCH[2]}""${BASH_REMATCH[3]}"fi
Isso pode gerar
Got09,19 and 14
se a hora atual for 09:19:14.
O REMATCHbit do BASH_REMATCHnome do array vem de "Correspondência de expressão regular", ou seja, "RE-Match".
Em bashshells não semelhantes a Bourne, pode-se também usar exprpara correspondência limitada de expressões regulares (usando apenas expressões regulares básicas).
É o mesmo que grep -Eentende apenas nos sistemas GNU e somente ao usar uma variável não citada como padrão [[ $var = $pattern ]](consulte [[ 'a b' =~ a\sb ]]vs p='a\sb'; [[ 'a b' =~ $p ]]). Observe também que a citação do shell afeta o significado dos operadores de ER e que alguns caracteres precisam ser citados para a tokenização do shell que pode afetar o processamento do RE. [[ '\' =~ [\/] ]]retorna falso. ksh93tem problemas ainda piores. Veja zsh(ou bash 3.1) para uma abordagem mais saudável, onde as cotações de shell e RE são claramente separadas. O [builtin de zshe yashtambém tem um =~operador.
Stéphane Chazelas
2
muito legal off-topic! 1 (
JJoao 27/17/17
@ StéphaneChazelas Como é "mais saudável" que ambas as partidas correspondam ao zsh ?: [[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]. Ou que um citado *também corresponde? [[ "This is a fine mess." =~ "T.........fin*es*" ]].
sorontar 30/01
É mais saudável (IMO), pois é muito mais simples. As citações de shell e escape de RE são claramente separadas. Em [[ a =~ .* ]]ou [[ a =~ '.*' ]]ou [[ a =~ \.\* ]], o mesmo .*ER é passado para o =~operador. OTH, em bash, [[ '\' =~ [)] ]]retorna um erro, você saberia sem tentar se [[ '\' =~ [\)] ]]corresponde? Que tal [[ '\' =~ [\/] ]](acontece no ksh93). Que tal c='a-z'; [[ a =~ ["$c"] ]](comparar com o =operador)? Veja também: [[ '\' =~ [^]"."] ]]que retorna falso ... Note que você pode fazer shopt -s compat31em bashpara obter o zshcomportamento.
Stéphane Chazelas
zsh/ bash -o compat31'S comportamento para [[ a =~ '.*' ]]também é consistente com [ a '=~' '.*' ](por [implementações que suporte =~) ou expr a : '.*'. OTOH, não é consistente com [[ a = '*' ]]vs [[ a = * ]](mas, os globs fazem parte da linguagem shell, enquanto os REs não).
Stéphane Chazelas
4
Você deve ler as páginas do manual do bash, na [[ expression ]]seção
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Para encurtar a história, =~é um operador, assim como ==e !=. Não tem nada a ver com a regex real na string à sua direita.
Você pode descobrir alguns exemplos demonstrando o uso =~na vida real ...?
George Vasiliou
11
@GeorgeVasiliou Eu o uso com bastante frequência em scripts que colocam a saída de um comando em uma variável. Em seguida, a variável é verificada para verificar se ela corresponde a algum padrão de sequência. Isso é útil, por exemplo, se você deseja executar alguma ação com base em alguma saída de erro desse comando.
Michael Martinez
@Sokel Para alguns, “RTFM” é mais fácil dizer do que fazer. ⋯ man [[ expresssion ]]e man [[não devolva nada. help [[retorna informações úteis - desde [[um comando bash interno - mas não diz se =~usa a sintaxe regex básica ou estendida. Text O texto que você citou é da página de manual do bash . Sei que você disse "leia as páginas de manual do bash", mas, a princípio, pensei que você pretendia ler as páginas de manual no bash. De qualquer forma, man bashretorna um arquivo enorme, com 4139 linhas (72 páginas). Pode ser pesquisado pressionando /▒▒▒, o que leva a uma expressão regular, cujo sabor - como =~- não é especificado.
Respostas:
Na
~
verdade, é parte do operador=~
que executa uma correspondência de expressão regular da string à sua esquerda e a expressão regular estendida à sua direita.Observe que a string deve ser citada e que a expressão regular não deve ser citada.
Um operador semelhante é usado na linguagem de programação Perl.
As expressões regulares entendidas por
bash
são as mesmas que o GNUgrep
entende com a-E
flag, ou seja, o conjunto estendido de expressões regulares.Um pouco fora de tópico, mas é bom saber:
Ao fazer a correspondência com uma expressão regular que contém grupos de captura, a parte da sequência capturada por cada grupo está disponível na
BASH_REMATCH
matriz. O zeroth / primeira entrada em Isto corresponde matriz para&
no padrão de substituiçãosed
de comando de substituição (ou$&
em Perl), que é o bit da cadeia que corresponde ao padrão, enquanto as entradas no índice 1 e seguintes corresponde a\1
,\2
, etc. . em umsed
padrão de substituição (ou$1
,$2
etc, em Perl), isto é, os bits correspondentes por cada parêntese.Exemplo:
Isso pode gerar
se a hora atual for 09:19:14.
O
REMATCH
bit doBASH_REMATCH
nome do array vem de "Correspondência de expressão regular", ou seja, "RE-Match".Em
bash
shells não semelhantes a Bourne, pode-se também usarexpr
para correspondência limitada de expressões regulares (usando apenas expressões regulares básicas).Um pequeno exemplo:
fonte
grep -E
entende apenas nos sistemas GNU e somente ao usar uma variável não citada como padrão[[ $var = $pattern ]]
(consulte[[ 'a b' =~ a\sb ]]
vsp='a\sb'; [[ 'a b' =~ $p ]]
). Observe também que a citação do shell afeta o significado dos operadores de ER e que alguns caracteres precisam ser citados para a tokenização do shell que pode afetar o processamento do RE.[[ '\' =~ [\/] ]]
retorna falso.ksh93
tem problemas ainda piores. Vejazsh
(ou bash 3.1) para uma abordagem mais saudável, onde as cotações de shell e RE são claramente separadas. O[
builtin dezsh
eyash
também tem um=~
operador.off-topic
! 1 ([[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. Ou que um citado*
também corresponde?[[ "This is a fine mess." =~ "T.........fin*es*" ]]
.[[ a =~ .* ]]
ou[[ a =~ '.*' ]]
ou[[ a =~ \.\* ]]
, o mesmo.*
ER é passado para o=~
operador. OTH, embash
,[[ '\' =~ [)] ]]
retorna um erro, você saberia sem tentar se[[ '\' =~ [\)] ]]
corresponde? Que tal[[ '\' =~ [\/] ]]
(acontece no ksh93). Que talc='a-z'; [[ a =~ ["$c"] ]]
(comparar com o=
operador)? Veja também:[[ '\' =~ [^]"."] ]]
que retorna falso ... Note que você pode fazershopt -s compat31
embash
para obter ozsh
comportamento.zsh
/bash -o compat31
'S comportamento para[[ a =~ '.*' ]]
também é consistente com[ a '=~' '.*' ]
(por[
implementações que suporte=~
) ouexpr a : '.*'
. OTOH, não é consistente com[[ a = '*' ]]
vs[[ a = * ]]
(mas, os globs fazem parte da linguagem shell, enquanto os REs não).Você deve ler as páginas do manual do bash, na
[[ expression ]]
seçãoAn additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Para encurtar a história,
=~
é um operador, assim como==
e!=
. Não tem nada a ver com a regex real na string à sua direita.fonte
=~
na vida real ...?man [[ expresssion ]]
eman [[
não devolva nada.help [[
retorna informações úteis - desde[[
um comando bash interno - mas não diz se=~
usa a sintaxe regex básica ou estendida. Text O texto que você citou é da página de manual do bash . Sei que você disse "leia as páginas de manual do bash", mas, a princípio, pensei que você pretendia ler as páginas de manual no bash. De qualquer forma,man bash
retorna um arquivo enorme, com 4139 linhas (72 páginas). Pode ser pesquisado pressionando/▒▒▒
, o que leva a uma expressão regular, cujo sabor - como=~
- não é especificado.