2012-07-27 1 views
15

Desidero trovare il numero di occorrenze di XXX nel mio documento in lattice che non hanno la forma di un comando come \XXX. Pertanto, sto cercando eventi che non sono preceduti da una barra rovesciata.grep backslash nella finestra di ricerca negativa

ho provato la seguente:

grep -c -e '(?<!\)XXX' test.tex #result: grep: Unmatched) or \) 
grep -c -e '(?<!\\)XXX' test.tex #result: 0 
grep -c -e "(?<!\\)XXX" test.tex #result: -bash: !\\: event not found 

nessuno di loro lavoro come previsto. In effetti, non capisco affatto l'ultimo messaggio di errore.

mio test.tex contiene solo le seguenti righe

%test.tex 

XXX 

\XXX 

Così il risultato atteso è 1.

Qualche idea?

Ps .: Sto lavorando in bash.

+0

FYI, nel tuo ultimo esempio, il! tra virgolette viene interpretato come espansione della cronologia, ma '! \\' non è un'espressione di espansione della cronologia valida. – chepner

risposta

28

Né le espressioni regolari standard né quelle estese supportano l'aspetto retrostante. Uso Perl regex:

grep -P '(?<!\\)xxx' test.tex 
+0

sembra funzionare, tranne che ho fatto un controllo incrociato in cui ho cercato 'XXX' per' \\ XXX' e per '(? Simon

+0

@Simon: Forse ci sono diverse occorrenze sulla stessa linea? – choroba

1

Provare a usare

grep -P '(?<!\\)\bXXX\b' test.tex 
+0

questo aiuta, ma secondo la mia pagina man per grep, -P è "altamente sperimentale", è ancora vero? c'è un modo non-perla per fare lookbehinds e lookaheads con grep? –

+2

@santiagoarizti: 'grep -P' è qui da molto tempo e non l'ho mai sentito dovrebbe essere considerato" sperimentale ".Dato che mi piace la funzionalità di espressione regolare di Perl, utilizzo sempre questa opzione e utilizzo il formato Perl. –

0

Se avete GNU grep, dovrebbe sostenere Perl-compatibili le espressioni regolari con --perl-regexp o l'opzione della riga di comando -P. La classica espressione regolare perl supporta solo classi di caratteri negate, ad esempio [^ a] significa qualsiasi carattere tranne "a".

Gli esempi che hai dato sembrano espressioni regolari compatibili con Perl, non classiche, e devi usare GNU grep con --perl-regexp o -P opzione da riga di comando o puoi installare grep abilitato a PCRE, per esempio "pcregrep" - non ha bisogno di alcuna opzione da riga di comando per PCRE, e quindi è più conveniente.

Inoltre, lo schema non assomiglia a un'asserzione negativa. Dovrebbe essere

(?!pattern) 
non

il

(?<!pattern) 

Trova di più qui: https://perldoc.perl.org/perlre.html

Se ti piace Perl compatibili le espressioni regolari e hanno perl, ma non hanno pcregrep o il vostro grep doesn' t support --perl-regexp, puoi usare script perl a riga singola che funzionano allo stesso modo di grep. Perl accetta lo stdin allo stesso modo di grep, ad es.

ipset list | perl -e "while (<>) {if (/packets(?! 0)/){print;};}" 
Problemi correlati