grep e escapando de um cifrão

22

Eu quero saber quais arquivos têm a string $Id$ .

grep \$Id\$  my_dir/mylist_of_files

retorna 0 ocorrências.

Eu descobri que tenho que usar

grep \$Id$ my_dir/mylist_of_files

Depois, vejo que o $Id é colorido na saída, ou seja, foi correspondido.

Como eu poderia corresponder ao segundo $ e por que não \$Id\$ funciona?

Não importa se o segundo $ é o último caractere ou não.

Eu uso grep 2,9.

Antes de postar minha pergunta, usei o google ...

Eu encontrei uma resposta

To search for a $ (dollar sign) in the file named test2, enter:

grep \$ test2

The \ (double backslash) characters are necessary in order to force the shell to pass a \$ (single backslash, dollar sign) to the grep command. The \ (single backslash) character tells the grep command to treat the following character (in this example the $) as a literal character rather than an expression character. Use the fgrep command to avoid the necessity of using escape characters such as the backslash.

mas não entendo por que grep \$Id funciona e por que grep \$Id\$ não funciona.

Estou um pouco confuso ...

    
por Luc M 18.02.2012 / 03:53

2 respostas

19

Existem 2 edições separadas aqui.

  1. grep usa Expressões regulares básicas (BRE), e $ é um caractere especial no BRE apenas no final de uma expressão. A conseqüência disso é que as duas instâncias de $ em $Id$ não são iguais. O primeiro é um caractere normal e o segundo é uma âncora que corresponde ao final da linha. Para fazer com que o segundo $ corresponda a um literal $ , você terá que recuar a barra invertida, ou seja, $Id\$ . Escapar do primeiro $ também funciona: \$Id\$ , e eu prefiro isso já que parece mais consistente.¹

  2. Existem dois mecanismos de escape / cotação completamente não relacionados em funcionamento aqui: o shell quoting e o regex entre aspas invertidas. O problema é que muitos caracteres que expressões regulares usam também são especiais para o shell e, além disso, o caractere de escape regex, a barra invertida, também é um caractere de citação de shell. É por isso que você costuma ver bagunças envolvendo barras duplas invertidas, mas eu não recomendo o uso de barras invertidas para shell citando expressões regulares, porque não é muito legível.

    Em vez disso, a maneira mais simples de fazer isso é primeiro colocar toda sua regex dentro de aspas simples como em 'regex' . A aspa simples é a forma mais strong de citar que o shell tem, portanto, contanto que o seu regex não contenha aspas simples, você não precisa mais se preocupar com o shell quoting e pode se concentrar na sintaxe pura do BRE.

Então, aplicando isso de volta ao seu exemplo original, vamos lançar a regex correta ( \$Id\$ ) dentro de aspas simples. O seguinte deve fazer o que quiser:

grep '\$Id\$' my_dir/my_file

A razão \$Id\$ não funciona porque após a remoção da cotação do shell (a maneira mais correta de dizer aspas do shell) é aplicada, a regex que grep vê é $Id$ . Como explicado em (1.), essa regex corresponde a um literal $Id apenas no final de uma linha porque o primeiro $ é literal, enquanto o segundo é um caractere especial de âncora.

¹ Observe também que, se você mudar para expressões regulares estendidas (ERE), por exemplo, Se você decidiu usar egrep (ou grep -E ), o caractere $ é sempre especial. Em $Id$ do ERE nunca corresponderia a nada porque você não pode ter caracteres após o final de uma linha, então \$Id\$ seria o único caminho a seguir.

    
por 18.02.2012 / 04:18
-1

Para pesquisar $Id$ em um arquivo: você pode usar: grep '\$id*' filename

    
por 30.01.2015 / 16:28