Cia*_*her 210 regex linux grep cygwin
可能重复:
如何在文件中搜索多行模式?使用pcregrep
我正在运行a grep
来查找任何*.sql文件,select
其后跟单词customerName
后跟单词from
.此select语句可以跨越多行,并且可以包含制表符和换行符.
我在下面尝试了一些变化:
$ grep -liIr --include="*.sql" --exclude-dir="\.svn*" --regexp="select[a-zA-Z0-
9+\n\r]*customerName[a-zA-Z0-9+\n\r]*from"
Run Code Online (Sandbox Code Playgroud)
然而,这只是永远运行.请问有人能帮助我正确的语法吗?
alb*_*fan 460
无需安装grep变量pcregrep,您可以使用grep进行多行搜索.
$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c
Run Code Online (Sandbox Code Playgroud)
说明:
-P
为grep激活perl-regexp(常规扩展的强大扩展)
-z
在行尾压缩换行符,将其替换为空字符.也就是说,grep知道行尾的位置,但将输入视为一个大行.
-o
打印只匹配.因为我们正在使用-z
,整个文件就像一个大行,所以如果匹配,整个文件将被打印; 这样它就不会那样做.
在正则表达式中:
(?s)
激活PCRE_DOTALL
,表示.
查找任何字符或换行符
\N
找到除换行之外的任何内容,即使已PCRE_DOTALL
激活
.*?
找到非.
同意模式,即尽快停止.
^
找到行的开头
\1
backreference to first group(\s*
)这是尝试找到相同的方法缩进
可以想象,此搜索在C(*.c
)源文件中打印main方法.
小智 160
grep我不是很好.但您的问题可以使用AWK命令解决.看看
awk '/select/,/from/' *.sql
Run Code Online (Sandbox Code Playgroud)
上面的代码将首先出现select
直到第一个序列from
.现在您需要验证返回的语句是否有customername
.为此,您可以管道结果.并且可以再次使用awk或grep.
你的根本问题是grep
一次只能运行一行 - 所以它找不到跨行的SELECT语句.
你的第二个问题是你正在使用的正则表达式没有处理SELECT和FROM之间出现的复杂性 - 特别是它省略了逗号,句号(句点)和空格,还有引号和任何可以在里面的内容引用的字符串.
我可能会使用基于Perl的解决方案,让Perl一次读取'paragraph'并应用正则表达式.缺点是必须处理递归搜索 - 当然还有模块,包括核心模块File :: Find.
概括地说,对于单个文件:
$/ = "\n\n"; # Paragraphs
while (<>)
{
if ($_ =~ m/SELECT.*customerName.*FROM/mi)
{
printf file name
go to next file
}
}
Run Code Online (Sandbox Code Playgroud)
这需要包装到一个sub中,然后由File :: Find的方法调用.