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激活
.*?找到非.同意模式,即尽快停止.
^ 找到行的开头
\1backreference 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的方法调用.
| 归档时间: |
|
| 查看次数: |
190069 次 |
| 最近记录: |