ksh93
e zsh
têm referências anteriores (ou mais precisamente 1 , referências a grupos de captura no substituto) suporte dentro de ${var/pattern/replacement}
, não bash
.
ksh93
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ printf '%s\n' "${var/*@(->*([[:space:]])+([^[:space:]]))*/}"
-> r1-ae0-2
zsh
:
$ var='Blah: -> r1-ae0-2 / [123]'
$ set -o extendedglob
$ printf '%s\n' "${var/(#b)*(->[[:space:]]#[^[:space:]]##)*/$match[1]}"
-> r1-ae0-2
( mksh
man page também menciona que versões futuras o suportarão com ${KSH_MATCH[1]}
para o primeiro grupo de captura. Ainda não disponível a partir de 2017-04-25).
No entanto, com bash
, você pode fazer:
$ [[ $var =~ -\>[[:space:]]*[^[:space:]]+ ]] &&
printf '%s\n' "${BASH_REMATCH[0]}"
-> r1-ae0-2
O que é melhor, pois verifica se o padrão é encontrado primeiro.
Se as expressões regulares de seu sistema suportarem \s
/ \S
, você também poderá fazer:
re='->\s*\S+'
[[ $var =~ $re ]]
Com zsh
, você pode obter todo o poder dos PCREs com:
$ set -o rematchpcre
$ [[ $var =~ '->\s*\S+' ]] && printf '%s\n' $MATCH
-> r1-ae0-2
Com zsh -o extendedglob
, consulte também:
$ printf '%s\n' ${(SM)var##-\>[[:space:]]#[^[:space:]]##}
-> r1-ae0-2
Portável:
$ expr " $var" : '.*\(->[[:space:]]*[^[:space:]]\{1,\}\)'
-> r1-ae0-2
Se houver várias ocorrências do padrão na string, o comportamento variará com todas essas soluções. No entanto, nenhum deles fornecerá uma lista separada por novas linhas de todas as correspondências, como na sua solução baseada em grep
do GNU.
Para fazer isso, você precisa fazer o loop manualmente. Por exemplo, com bash
:
re='(->\s*\S+)(.*)'
while [[ $var =~ $re ]]; do
printf '%s\n' "${BASH_REMATCH[1]}"
var=${BASH_REMATCH[2]}
done
Com zsh
, você pode recorrer a esse tipo de truque para armazenar todas as correspondências em uma matriz:
set -o extendedglob
matches=() n=0
: ${var//(#m)->[[:space:]]#[^[:space:]]##/${matches[++n]::=$MATCH}}
printf '%s\n' $matches
As referências anteriores 1 designam mais comumente um padrão que faz referência ao que foi correspondido por um grupo anterior. Por exemplo, a expressão regular \(.\)
basic corresponde a um único caractere seguido pelo mesmo caractere (corresponde a aa
, não a ab
). Esse
é uma referência anterior ao grupo de captura \(.\)
no mesmo padrão.
ksh93
suporta referências anteriores em seus padrões (por exemplo, ls -d -- @(?)
listará os nomes de arquivos que consistem em dois caracteres idênticos), não outros shells. BREs e PCREs padrão suportam referências anteriores, mas não ERE padrão, embora algumas implementações ERE o suportem como uma extensão. bash
[[ foo =~ re ]]
usa EREs.
[[ aa =~ (.) ]]
não coincide, mas
re='(.)'; [[ aa =~ $re ]]
pode se os EREs do sistema o suportarem.