2012-07-27 15 views
15

Ich möchte die Anzahl der Vorkommen von XXX in meinem Latex-Dokument, die nicht in der Form eines Befehls als \XXX sind. Daher suche ich nach Vorkommen, denen kein Backslash vorangestellt ist.Grep Backslash in negativen Lookbehind

Ich habe versucht, die folgenden:

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 

keiner von ihnen wie vorgesehen. Tatsächlich verstehe ich die letzte Fehlermeldung überhaupt nicht.

Mein test.tex enthält nur die folgenden Zeilen

%test.tex 

XXX 

\XXX 

So das erwartete Ergebnis ist 1.

Irgendwelche Ideen?

Ps .: Ich arbeite in bash.

+0

FYI, in Ihrem letzten Beispiel, der! in doppelten Anführungszeichen wird als Verlaufserweiterung interpretiert, aber '! \\' ist kein gültiger Ausdruck für die Verlaufserweiterung. – chepner

Antwort

28

Weder Standard noch erweiterte reguläre Ausdrücke unterstützen den Blick dahinter. Verwenden Perl reguläre Ausdrücke:

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

das scheint zu funktionieren, außer dass ich eine Gegenprobe gemacht habe, wo ich nach 'XXX' für' \\ XXX' und nach '(? Simon

+0

@Simon: Vielleicht gibt es mehrere Vorkommen in der gleichen Zeile? – choroba

1

Try

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

das hilft, aber nach meiner Manpage für Grep, -P ist "sehr experimentell", ist das immer noch wahr? Gibt es einen nicht-perle Weg um Lookbehinds und Lookaheads mit Grep zu machen? –

+2

@santiagarizti: 'grep -P ist hier für sehr lange Zeit und ich habe nie gehört, es sollte als" experimentell "betrachtet werden.Da ich Perl-Funktionalität für reguläre Ausdrücke mag, gehe ich immer mit diesem Schalter und verwende Perl-Format. –

0

zu verwenden Wenn Sie GNU grep haben, sollte es Perl-kompatible reguläre Ausdrücke mit --perl-regexp oder -P-Befehlszeilenoption unterstützen. Der klassische Perl-Regular-Ausdruck unterstützt nur negierte Zeichenklassen, zum Beispiel bedeutet [^ a] jedes Zeichen außer "a".

Die Beispiele, die Sie geben, sehen aus wie Perl-kompatible reguläre Ausdrücke, nicht klassische, und Sie müssen GNU grep mit --perl-regexp oder -P Befehlszeile-Option verwenden oder Sie können PCRE-fähige Grep installieren, z.B "pcregrep" - es benötigt keine Befehlszeilenoptionen für PCRE und ist daher bequemer.

Auch Sie Muster sieht nicht wie eine negative Behauptung aus. Es sollte

(?!pattern) 

nicht die

(?<!pattern) 

mehr finden hier sein: https://perldoc.perl.org/perlre.html

Wenn Sie Perl-kompatible reguläre Ausdrücke und haben Perl, aber nicht über pcregrep oder Ihre grep doesn‘ t support --perl-regexp, können Sie One-Line-Perl-Skripte, die die gleiche Funktionsweise wie Grep. Perl akzeptiert stdin genauso wie grep, z.