2012-05-10 11 views
9

Ho un po 'di problema con grep che non riesco a capire. Sto cercando di cercare tutte le istanze delle parole minuscole racchiuse tra virgolette (stringhe C) in un set di file sorgente. Utilizzando bash e grep GNU:Modello di grep che corrisponde alla stringa minuscola racchiusa tra virgolette

grep -e '"[a-z]+"' *.cpp 

mi dà nessun risultato, mentre

grep -e '"[a-z]*"' *.cpp 

mi dà Partite come "Abc", che non è solo caratteri minuscoli. Qual è l'espressione regolare corretta per abbinare solo "abc"?

+0

Il tuo secondo regex sembra buono. L'ho provato e non corrisponde ai caratteri maiuscoli. – Misha

+1

@Mike ti stai dimenticando dell'ordine di fascicolazione specifico della locale. –

+0

@Don Grazie, non ci ho nemmeno pensato! – Misha

risposta

8

Stai dimenticando per sfuggire alla meta personaggi.

grep -e '"[a-z]\+"' 

Per la seconda parte, il motivo per cui si abbinano i caratteri multi-caso è a causa delle impostazioni locali. Come segue:

$ echo '"Abc"' | grep -e '"[a-z]\+"' 
"Abc" 
$ export LC_ALL=C 
$ echo '"Abc"' | grep -e '"[a-z]\+"' 
$ 

per ottenere il comportamento "ascii-like", è necessario impostare le impostazioni internazionali a "C", come specificato nella pagina di grep man:

All'interno di un'espressione parentetica, un'espressione di intervallo è composta da due caratteri separati da un trattino. Corrisponde a qualsiasi singolo carattere che ordina tra i due caratteri, compreso, utilizzando la sequenza di fascicolazione e il set di caratteri della locale. Ad esempio, nel locale C predefinito di , [a-d] è equivalente a [abcd]. Molte localizzazioni ordinano i caratteri nell'ordine dei dizionari e in queste localizzazioni [a-d] è in genere non equivalente a [abcd]; potrebbe essere equivalente a [aBbCcDd], per esempio. Per ottenere l'interpretazione tradizionale della espressioni fra parentesi quadre, è possibile utilizzare la versione locale C impostando la variabile d'ambiente LC_ALL al valore C.

+0

Yup, locali stupidi. Inoltre, perché devo sfuggire al +? Penserei che se volessi un letterale + lo sfuggirei e che un + nudo sarebbe considerato il metacarattere. –

+1

Nelle espressioni regolari di base i meta-caratteri?, +, {, |, (E) perdono il loro significato speciale; usa invece le versioni backslash \ ?, \ +, \ {, \ |, \ (e \). Per ottenere un'espressione regolare, utilizzare -E –

+0

-E, grazie. Le vecchie abitudini sono dure a morire. –

1

mascherare il +

grep -e '"[a-z]\+"' *.cpp 

o utilizzare egrep:

egrep '"[a-z]+"' *.cpp 

Forse hai avuto -E in mente:

grep -E '"[a-z]+"' *.cpp 

Il -e minuscolo viene utilizzato, ad esempio, per specificare più modelli di ricerca.

La phaenomenon di caratteri maiuscoli potrebbe origine dal proprio locale - che si può prevenire con:

LC_ALL=C egrep '"[a-z]+"' *.cpp 
+0

Pensavo che grep -e fosse egrep. Immagino di essermi sbagliato. –

+0

Sì, lo pensavo anch'io, ma poiché la mia abitudine è usare egrep, ho provato egrep senza guardare più vicino all'opzione -e, e appena dopo aver avuto successo con egrep, ho capito che il -e dovrebbe fare una cosa simile - I pensavo lo stesso. Ma l'opzione corretta è -E, con il maiuscole E. Si prega di cercare te stesso nella pagina di manuale. –

0

Probabilmente bisogno di sfuggire alla +:

grep -e '"[a-z]\+"' *.cpp 
0

Se non si vuole pasticciare con locali, questo ha funzionato per me:

grep -e '"[[:lower:]]\+"' 
Problemi correlati