grep e sfuggire a un segno di dollaro


31

Voglio sapere quali file hanno la stringa $Id$.

grep \$Id\$  my_dir/mylist_of_files

restituisce 0 occorrenze.

Ho scoperto che devo usare

grep \$Id$ my_dir/mylist_of_files

Quindi vedo che $Idè colorato nell'output, cioè è stato abbinato.

Come potrei abbinare il secondo $e perché non \$Id\$funziona.

Non importa se il secondo $è l'ultimo personaggio o meno.

Io uso grep2.9.


Prima di pubblicare la mia domanda, ho usato google ...

Ho trovato una risposta

Per cercare un $ (simbolo del dollaro) nel file denominato test2, immettere:

grep \\ $ test2

I caratteri \\ (doppia barra rovesciata) sono necessari per forzare la shell a passare un \ $ (barra rovesciata singola, segno del dollaro) al comando grep. Il carattere \ (barra rovesciata singola) indica al comando grep di trattare il carattere seguente (in questo esempio $) come un carattere letterale piuttosto che un carattere di espressione. Utilizzare il comando fgrep per evitare la necessità di utilizzare caratteri di escape come la barra rovesciata.

ma non capisco perché grep \$Idfunzioni e perché grep \\$Id\\$no.

Sono un po 'confuso ...

Risposte:


25

Ci sono 2 problemi separati qui.

  1. grepusa le espressioni regolari di base (BRE) ed $è un carattere speciale di BRE solo alla fine di un'espressione. La conseguenza di ciò è che le 2 istanze di $in $Id$non sono uguali. Il primo è un personaggio normale e il secondo è un'ancora che corrisponde alla fine della linea. Per rendere $letterale la seconda partita $dovrai scappare indietro, cioè $Id\$. Anche l'escaping del primo $funziona :, \$Id\$e preferisco questo poiché sembra più coerente .¹

  2. Esistono due meccanismi di escape / quoting completamente non correlati qui: quotazione della shell e quotazione di backslash regex. Il problema è che molti caratteri che usano le espressioni regolari sono speciali anche per la shell, e per di più il carattere di escape regex, la barra rovesciata, è anche un carattere di citazione della shell. Questo è il motivo per cui vedi spesso disordine che coinvolgono doppie barre rovesciate, ma non consiglio di usare barre rovesciate per la shell che cita espressioni regolari perché non è molto leggibile.

    Invece, il modo più semplice per farlo è prima di tutto mettere la tua regex tra virgolette singole come in 'regex'. La virgoletta singola è la forma più forte di quotazione della shell, quindi finché la tua regex non contiene virgolette singole, non devi più preoccuparti delle quotazioni della shell e puoi concentrarti sulla sintassi BRE pura.

Quindi, applicandolo al tuo esempio originale, gettiamo la regex ( \$Id\$) corretta tra virgolette singole. Quanto segue dovrebbe fare quello che vuoi:

grep '\$Id\$' my_dir/my_file

Il motivo \$Id\$non funziona perché dopo la rimozione della citazione della shell (il modo più corretto di dire la citazione della shell) viene applicata la regex che grepvede $Id$. Come spiegato in (1.), questa regex corrisponde a un letterale $Idsolo alla fine di una riga perché il primo $è letterale mentre il secondo è un carattere di ancoraggio speciale.

¹ Si noti inoltre che se si passa a Extended Regular Expressions (ERE), ad esempio se si decide di utilizzare egrep(o grep -E), il $personaggio è sempre speciale. In ERE $Id$non corrisponderebbe mai a nulla perché non puoi avere personaggi dopo la fine di una riga, quindi \$Id\$sarebbe l'unica strada da percorrere.


3
Per evitare che grep interpreti il ​​suo primo parametro come espressione regolare, puoi anche farlo grep -F '$Id$'.
jfg956,

Nella mia shell (bash 4.3.42) grep '$Id\$' ...e grep \$Id\\$ ...lavoro
nitsas

2
E se questo è un comando in un makefile, è inoltre necessario sfuggire alla $con un precedente $: grep '$$Id\$$'. stackoverflow.com/a/2382810/2097284
Camille Goudeseune

-2

Per cercare $Id$in un file: puoi usare:grep '\$id*' filename


2
Che corrisponderà a tutto ciò che inizia $id, quindi anche $ideaper esempio, non solo $id$.
terdon
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.