2012-07-27 10 views
15

Quiero encontrar el número de ocurrencias de XXX en mi documento de látex que no tienen la forma de un comando como \XXX. Por lo tanto, estoy buscando ocurrencias que no estén precedidas por una barra diagonal inversa.grep backslash en negativo lookbehind

He intentado lo siguiente:

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 

ninguno de ellos funciona como es debido. De hecho, no entiendo el último mensaje de error.

Mi test.tex sólo contiene las siguientes líneas

%test.tex 

XXX 

\XXX 

Así, el resultado esperado es 1.

¿Alguna idea?

Ps .: Estoy trabajando en bash.

+0

FYI, en su último ejemplo, el! en comillas dobles se interpreta como una expansión de historial, pero '! \\' no es una expresión de expansión de historial válida. – chepner

Respuesta

28

Ni las expresiones regulares ni las expresiones regulares extendidas admiten la apariencia detrás. Usar expresiones regulares de Perl:

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

esto parece funcionar, excepto que hice una comprobación cruzada donde busqué 'XXX' para' \\ XXX' y para '(? Simon

+0

@Simon: ¿Tal vez hay varias ocurrencias en la misma línea? – choroba

1

Intente utilizar

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

esto ayuda, pero según mi página de manual para grep, -P es "altamente experimental", ¿esto sigue siendo cierto? ¿Hay una forma no perlada de mirar detrás y mirar con grep? –

+2

@santiagoarizti: 'grep -P' está aquí por mucho tiempo y nunca escuché que debería considerarse" experimental ".Como me gusta la funcionalidad de expresión regular de Perl, siempre uso este modificador y uso el formato Perl. –

0

Si tiene grep de GNU, debería apoyar Compatibles con Perl expresiones regulares con --perl-expresión regular o una opción de línea de comandos -P. La expresión regular perl clásica solo admite clases de caracteres negadas, por ejemplo, [^ a] significa cualquier carácter excepto "a".

Los ejemplos que le dio parecerse a las expresiones regulares compatibles con Perl, uno no clásica, y hay que usar GNU grep con --perl-expresión regular o una opción de línea de comandos -P o puede instalar grep habilitado para PCRE, p.ej "pcregrep" - no necesita opciones de línea de comandos para PCRE, y por lo tanto es más conveniente.

Además, su patrón no parece una afirmación negativa. Debe ser

(?!pattern) 
no

la

(?<!pattern) 

Encuentra más información aquí: https://perldoc.perl.org/perlre.html

Si te gusta expresiones regulares compatibles con Perl y tienen Perl, pero no tienen pcregrep o su grep doesn' Soporte t --perl-regexp, usted puede una línea de scripts perl que funcionan de la misma manera que grep. Perl acepta stdin de la misma manera que grep, p.

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