27

我想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 中工作。

4

4 回答 4

54

标准正则表达式和扩展正则表达式都不支持后面的样子。使用 Perl 兼容的正则表达式:

grep -P '(?<!\\)xxx' test.tex
于 2012-07-27T09:37:41.300 回答
1

尝试使用

grep -P '(?<!\\)\bXXX\b' test.tex
于 2012-07-27T15:13:08.890 回答
0

我的 MacOS Catalina 上的grep版本甚至没有-PPerl 风格正则表达式的标志,


    $ 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;
            }
        }
    }

于 2020-08-17T02:43:23.503 回答
0

如果你有 GNU grep,它应该支持带有 --perl-regexp 或 -P 命令行选项的 Perl 兼容的正则表达式。经典的 perl 正则表达式只支持否定字符类,例如,[^a] 表示除 "a" 之外的任何字符。

您提供的示例看起来像 Perl 兼容的正则表达式,而不是经典的,您必须使用带有 --perl-regexp 或 -P 命令行选项的 GNU grep,或者您可以安装启用 PCRE 的 grep,例如“pcregrep” - PCRE不需要任何命令行选项,因此更方便。

此外,您的模式看起来不像否定断言。它应该是

(?!pattern)

不是

(?<!pattern)

在此处查找更多信息:https ://perldoc.perl.org/perlre.html

如果您喜欢与 perl 兼容的正则表达式并且有 perl 但没有 pcregrep 或者您的 grep 不支持 --perl-regexp,您可以使用与 grep 相同的方式工作的单行 perl 脚本。Perl 像 grep 一样接受标准输入,例如

ipset list | perl -e "while (<>) {if (/packets(?! 0 )/){print;};}"
于 2017-04-22T06:38:30.910 回答