Regex Grep用于不以“开头”的行//&引用;

Regex Grep用于不以“开头”的行//&引用;,regex,bash,grep,Regex,Bash,Grep,我正在尝试为不以“/”开头的行(即C++风格的注释)编写一个正则表达式到grep,但失败了。我知道“grep-v”选项,但我正在尝试学习如何单独使用regex实现这一点。 我已经搜索并找到了关于对不以字符开头的行进行grep的各种答案,甚至还有一个关于如何对不以字符串开头的行进行grep的答案,但我无法根据我的情况调整这些答案,我不明白我的错误是什么 > cat bar.txt hello //world > cat bar.txt | grep "(?!\/\/)" -bash:

我正在尝试为不以“/”开头的行(即C++风格的注释)编写一个正则表达式到grep,但失败了。我知道“grep-v”选项,但我正在尝试学习如何单独使用regex实现这一点。 我已经搜索并找到了关于对不以字符开头的行进行grep的各种答案,甚至还有一个关于如何对不以字符串开头的行进行grep的答案,但我无法根据我的情况调整这些答案,我不明白我的错误是什么

> cat bar.txt
hello
//world
> cat bar.txt | grep "(?!\/\/)"
-bash: !\/\/: event not found
我不确定“未发现事件”是关于什么的。我找到的一个答案使用了paren问号感叹号字符串paren,我在这里做了,但仍然失败

> cat bar.txt | grep "^[^\/\/].+"
(no output)
我发现的另一个答案使用了方括号内的插入符号,并解释说,这种语法意味着“搜索方括号中没有的内容(除了插入符号)。我认为“+”表示“任何内容中的一个或多个”,但我不确定这是否正确,如果正确,它与“*”的区别是什么

简而言之:我如何构造一个正则表达式来传递给grep以搜索不以“/”开头的行

更具体地说,我试图搜索前面没有“/”的带有“#include”的行


谢谢。

您必须使用
-p
(perl)选项:


您必须使用
-p
(perl)选项:


对于不以“/”开头的行,可以使用
(^[^/]{2}.*$)
对于不以“/”开头的行,可以使用
(^[^/]{2}.*$)

  • 您使用的是反向前瞻,这是PCRE功能,需要
    -P
    选项
  • 如果没有启动锚,你的消极前瞻将无法工作
  • 这当然需要
    gnu grep
  • 必须使用单引号才能在正则表达式中使用
    ,否则将尝试使用正则表达式中
    之后的文本展开历史记录,原因是
    !\/\/:未找到事件
    错误
  • 因此,您可以使用:

    grep -P '^(?!\h*//)' file
    hello
    
    grep '^[[:space:]]*#[[:space:]]*include[[:space:]]*["<]'
    
    \h
    匹配0个或多个水平空白

    如果没有
    -p
    或非gnu grep,您可以使用
    grep-v

    grep -v '^[[:blank:]]*//' file
    hello
    
  • 您使用的是反向前瞻,这是PCRE功能,需要
    -P
    选项
  • 如果没有启动锚,你的消极前瞻将无法工作
  • 这当然需要
    gnu grep
  • 必须使用单引号才能在正则表达式中使用
    ,否则将尝试使用正则表达式中
    之后的文本展开历史记录,原因是
    !\/\/:未找到事件
    错误
  • 因此,您可以使用:

    grep -P '^(?!\h*//)' file
    hello
    
    grep '^[[:space:]]*#[[:space:]]*include[[:space:]]*["<]'
    
    \h
    匹配0个或多个水平空白

    如果没有
    -p
    或非gnu grep,您可以使用
    grep-v

    grep -v '^[[:blank:]]*//' file
    hello
    
    要查找
    #包括前面没有
    /
    (或
    /*
    ..)的
    行,可以使用:

    grep -P '^(?!\h*//)' file
    hello
    
    grep '^[[:space:]]*#[[:space:]]*include[[:space:]]*["<]'
    
    如果您必须处理包含此类符号的软件,(a)我很同情您,(b)在查找
    #include
    行之前,将代码修改为更正统的样式。它会发现误报,例如:

    #/*comment*/include/*comment*/<stdio.h>
    #\
    include\
    <stdio.h>
    
    /* Do not include this:
    #include <does-not-exist.h>
    */
    
    要查找
    #包括前面没有
    /
    (或
    /*
    ..)的
    行,可以使用:

    grep -P '^(?!\h*//)' file
    hello
    
    grep '^[[:space:]]*#[[:space:]]*include[[:space:]]*["<]'
    
    如果您必须处理包含此类符号的软件,(a)我很同情您,(b)在查找
    #include
    行之前,将代码修改为更正统的样式。它会发现误报,例如:

    #/*comment*/include/*comment*/<stdio.h>
    #\
    include\
    <stdio.h>
    
    /* Do not include this:
    #include <does-not-exist.h>
    */
    

    第一行告诉您问题来自
    bash
    (您的shell).Bash找到
    ,并尝试将您最后输入的以
    \/\/
    开头的命令注入到您的命令中。要避免这种情况,您需要转义
    或使用单引号。例如
    ,请尝试
    !cat
    ,它将执行您输入的最后一个以
    cat
    开头的命令

    您不需要转义
    /
    ,它在正则表达式中没有特殊意义。您也不需要编写复杂的正则表达式来反转匹配。相反,只需将
    -v
    参数提供给grep。大多数情况下,简单更好。而且您也不需要将文件cat到grep。只需给grep文件名。例如

    grep -v "^//" bar.txt | grep "#include"
    
    如果你真的很想使用正则表达式,那么一个简单的正则表达式应该是这样的(匹配字符串的开头
    ^
    ,任意数量的空格
    [:space:]*
    ,正好两个反斜杠
    /{2}
    ,任意数量的字符
    *
    ,后跟
    \include
    ):


    第一行告诉您问题来自
    bash
    (您的shell).Bash找到
    ,并尝试将您最后输入的以
    \/\/
    开头的命令注入到您的命令中。要避免这种情况,您需要转义
    或使用单引号。例如
    ,请尝试
    !cat
    ,它将执行您输入的最后一个以
    cat
    开头的命令

    您不需要转义
    /
    ,它在正则表达式中没有特殊意义。您也不需要编写复杂的正则表达式来反转匹配。相反,只需将
    -v
    参数提供给grep。大多数情况下,简单更好。而且您也不需要将文件cat到grep。只需给grep文件名。例如

    grep -v "^//" bar.txt | grep "#include"
    
    如果你真的很想使用正则表达式,那么一个简单的正则表达式应该是这样的(匹配字符串的开头
    ^
    ,任意数量的空格
    [:space:]*
    ,正好两个反斜杠
    /{2}
    ,任意数量的字符
    *
    ,后跟
    \include
    ):


    如果您不喜欢
    grep-v
    ,那么您可以使用awk:

    awk '!/^\/\//' file
    
    由于awk支持复合条件,而不仅仅是regexp,因此通常比grep更容易指定要与awk匹配的内容,例如使用grep按任意顺序搜索
    a
    b

    grep -E 'a.*b|b.*a`