我想在我的乳胶文档中找到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工作。
答案 0 :(得分:35)
标准和扩展正则表达式都不支持后面的外观。使用Perl正则表达式:
grep -P '(?<!\\)xxx' test.tex
答案 1 :(得分:1)
尝试使用
grep -P '(?<!\\)\bXXX\b' test.tex
答案 2 :(得分:0)
如果你有GNU grep,它应该使用--perl-regexp或-P命令行选项支持与Perl兼容的正则表达式。经典的perl正则表达式仅支持否定的字符类,例如,[^ a]表示除了&#34; a&#34;之外的任何字符。
您提供的示例看起来像Perl兼容的正则表达式,而不是经典表达式,您必须使用GNU grep和--perl-regexp或-P命令行选项,或者您可以安装支持PCRE的grep,例如: &#34; pcregrep&#34; - 它不需要PCRE的任何命令行选项,因此更方便。
此外,您的模式看起来不像负面断言。它应该是
(?!pattern)
不是
(?<!pattern)
在此处查找更多内容:https://perldoc.perl.org/perlre.html
如果您喜欢与Perl兼容的正则表达式并且使用perl但没有pcregrep或者您的grep不支持--perl-regexp,那么您可以使用相同方式的单行perl脚本像grep。 Perl以与grep相同的方式接受stdin,例如
ipset list | perl -e "while (<>) {if (/packets(?! 0 )/){print;};}"
答案 3 :(得分:0)
我的MacOS Catalina上的grep
版本甚至没有Perl样式正则表达式的-P
标志,
$ grep --version
grep (BSD grep) 2.5.1-FreeBSD
因此,我刚刚滚动了自己的grep -l
命令版本,该命令需要获取与否定的正则表达式匹配的文件列表,以下是源代码,可以随时适应您自己的需求,>
#!/usr/bin/perl
use strict;
use warnings;
# Tries to mimic at least partially `grep -l` command, and provides support for look-arounds using Perl regex'
# Usage: ls <some folder> | grepList.pl <reg-ex>
# Algorithm:
# Open each file in the list supplied
# Apply regex to each line, as soon as it matches output file name to STDOUT and continue to next file
# If EOF file reached, means file did not match, do not print file name, and move on to next file
# Runtime complexity: O(m * n), where m is number of files and n is the maximum number of lines a file can have
# Space complexity: O(1), no intermediary memory storage needed
my $reg_ex = qr/$ARGV[0]/;
while(<STDIN>) {
chop($_);
my $file = $_;
open(IN, $file) || die "Unable to open $file: $!";
while(<IN>) {
my $line = $_;
if ($line =~ /$reg_ex/) {
print "$file\n";
last;
}
}
}