Regex Grep用于不以“开头”的行//&引用;
我正在尝试为不以“/”开头的行(即C++风格的注释)编写一个正则表达式到grep,但失败了。我知道“grep-v”选项,但我正在尝试学习如何单独使用regex实现这一点。 我已经搜索并找到了关于对不以字符开头的行进行grep的各种答案,甚至还有一个关于如何对不以字符串开头的行进行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:
> 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}.*$)
-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
-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`