Grep обратная косая черта в отрицательном lookbehind

Я хочу найти количество вхождений XXX в моем латексном документе, которые не представлены в виде команды \XXX. Поэтому я ищу вхождения, которым не предшествует обратная косая черта.

Я попробовал следующее:

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

ни один из них не работает должным образом. На самом деле я вообще не понимаю последнее сообщение об ошибке.

Мой test.tex содержит только следующие строки

%test.tex

XXX

\XXX

Таким образом, ожидаемый результат 1.

Любые идеи?

Ps: Я работаю в bash.

Ответы

Ответ 1

Ни стандартные, ни расширенные регулярные выражения не поддерживают внешний вид. Использовать регулярные выражения Perl:

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

Ответ 2

Попробуйте использовать

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

Ответ 3

Если у вас есть GNU grep, он должен поддерживать регулярные выражения, совместимые с Perl, с параметром командной строки -perl-regexp или -P. Классическое регулярное выражение perl поддерживает только отрицательные классы символов, например, [^ a] означает любой символ, кроме "a".

Приведенные вами примеры выглядят как Perl-совместимые регулярные выражения, а не классические, и вы должны использовать GNU grep с параметром командной строки -perl-regexp или -P или вы можете установить grep с поддержкой PCRE, например. "pcregrep" - ему не нужны параметры командной строки для PCRE и, следовательно, более удобно.

Кроме того, шаблон не похож на отрицательное утверждение. Это должно быть

(?!pattern)

не

(?<!pattern)

Подробнее здесь: https://perldoc.perl.org/perlre.html

Если вам нравятся perl-совместимые регулярные выражения и имеют perl, но не имеют pcregrep, или ваш grep не поддерживает -perl-regexp, вы можете использовать однострочные Perl-скрипты, которые работают так же, как grep. Perl принимает stdin так же, как grep, например.

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