Uso de aspas em expressões regulares do GNU grep

3

Eu pude ver que certos padrões no GNU Grep podem ser colocados dentro de colchetes e outros não precisam ser. Por exemplo, a correspondência do início de uma palavra só funciona se estiver entre aspas.

user@host:~/Desktop$ grep -E '\<H' test
Hello World
user@host:~/Desktop$ grep -E \<H test

[teste contém a string Hello World]

Mas o final correspondente e o início do arquivo funcionam sem dólar:

user@host:~/Desktop$ egrep d$ test
Hello World

Por que isso acontece? E qual é a regra?

    
por user3539 01.03.2013 / 01:13

2 respostas

6

As aspas são expandidas pelo shell, elas determinam o que grep vê.

Com grep -E '\<H' , os caracteres entre as aspas simples são passados literalmente, então grep vê o regex \<H contendo a âncora do início da palavra \< .

Com grep -E \<H , o caractere de barra invertida remove o significado especial de < no shell e grep vê o regex <H . Você veria correspondências para uma linha como <Hello> .

Com grep -E <H , o caractere < teria seu significado especial no shell como um caractere de redirecionamento, portanto grep receberia o conteúdo do arquivo chamado H em sua entrada padrão.

Com grep 'd$' ou grep d\$ , o cifrão é citado, por isso alcança grep : a regex é d$ , correspondendo a d no final de uma linha.

Com grep d$ test , o sinal $ não é seguido por um nome de variável válido ou por pontuação válida ( ${ , $( ). Quando isso acontece, o shell passa o sinal $ literalmente, então grep vê novamente o regex d$ . $ só é expandido quando é seguido por um nome de variável válido (mesmo se a variável for indefinida - o que importa é que um nome seja seguido, como em $PATH ou $fioejsfoeij ou variáveis de caractere único, como $- ou $$ ), ou nas construções ${…} , $(…) , $((…)) (também $[…] no bash e zsh e mais construções no zsh).

As regras completas para expansão de shell são complexas demais para serem descritas em um post ou em uma dúzia. Na prática, basta lembrar os casos habituais:

  • \ (barra invertida) cita o caractere seguinte, a menos que seja uma nova linha, e a barra invertida é sempre removida;
  • '…' (aspas simples) cita todos os caracteres, exceto ' ;
  • "…" (aspas duplas) citam todos os caracteres, exceto "$\' e \ entre aspas duplas, fazendo com que o caractere a seguir seja interpretado literalmente e só seja removido se o próximo caractere for especial.
por 01.03.2013 / 01:24
0

O \< é primeiro escapado pelo shell e seu valor se torna o caractere literal < . Portanto, a expressão regular passada para grep é a string <H , que não tem um significado especial.

E se você precisar de um conhecimento profundo dessa relação em particular, deve consultar a resposta de Gilles.

    
por 01.03.2013 / 01:23