Bash: truque de ganância de regex para padrões complexos de fechamento

Bash regex não oferece suporte a modificadores de ganância como o “?” (ser não ganancioso).

Portanto, se alguém quiser corresponder a padrões delimitadores (como “corresponder tudo dentro de aspas” ou “corresponder tudo dentro de uma tag HTML”), você deve contar com algumas soluções alternativas.

Um truque comum para padrões simples (correspondência de um único caractere), como tags XML, é combinar a parte esquerda e tudo depois sendo ganancioso, em seguida, negar a correspondência do lado direito, significando “correspondência de [mão esquerda] e tudo o que é não [mão direita] “:

text="aaa<skipme>bbb<skipmetoo>ccc"
echo
"${text//<*([^>])>/}"
# outputs "aaabbbccc"

Mas com padrões de fechamento mais complexos, por exemplo “[[corresponder a tudo dentro]]”, que é bastante comum para marcação wiki. O truque acima não funcionará, pois você depende da negação do grupo de caracteres que corresponderá a caracteres únicos. Tentei jogar com o operador de negação “! ()”, Mas falhei miseravelmente, então uma solução que descobri foi realizar uma substituição de 2 passagens. Primeiro, substituo todos os “[[” e “]]” por um único caractere facilmente distinguível e, em seguida, substituo-o pela string final desejada:

# Char 0x06 is the non-printable "ACK"
# You need to use as $var because the regexp
# won't accept "x06" in the pattern
ch
=`echo -e 'x06'`
text
="aaa<<skipme>>bbb<<skipmetoo>>ccc"
tmp
="${text//@(<<|>>)/$ch}"
echo
"${tmp//${ch}*([^${ch}])${ch}}"
# "aaabbbccc"

Uma postagem mais detalhada em meu blog:

http://monospaced-thoughts.com/2011/07/05/bash-regexp-trick/