为了账号安全,请及时绑定邮箱和手机立即绑定

需要多行搜索的regex(Grep)

需要多行搜索的regex(Grep)

斯蒂芬大帝 2019-07-10 09:38:21
需要多行搜索的regex(Grep)我在运行一个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"然而,这只是永无止境。有人能帮我掌握正确的语法吗?
查看完整描述

3 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

不需要安装grep变体pcregrep,就可以使用grep进行多行搜索。

$ grep -Pzo "(?s)^(\s*)\N*main.*?{.*?^\1}" *.c

说明:

-P激活grep的perl-regexp(正则表达式的强大扩展)

-z在行尾抑制换行符,将其替换为空字符。也就是说,grep知道行的末尾,但是将输入看作一个大行。

-o只打印匹配。因为我们用-z,整个文件就像一个大行,所以如果有匹配,整个文件就会被打印出来;这样它就不会这样做了。

在regexp:

(?s)激活PCRE_DOTALL,这意味着.查找任何字符或换行符

\N找到除了换行符以外的任何东西,即使PCRE_DOTALL激活

.*?找到,发现.在非贪婪模式下,即尽快停止。

^找到行的开始

\1对第一组的反向引用(\s*)这是试图找到方法的相同缩进

可以想象,这个搜索在C中打印主方法(*.c)源文件。


查看完整回答
反对 回复 2019-07-10
?
开满天机

TA贡献1786条经验 获得超12个赞

我在GREP方面不是很好。但是你的问题可以用AWK命令。只是看看

awk '/select/,/from/' *.sql

以上代码将产生于select直到第一个序列from..现在,您需要验证返回的语句是否具有customername或者不是。为此,您可以通过管道传递结果。并且可以再次使用awk或grep。


查看完整回答
反对 回复 2019-07-10
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

你的根本问题是grep一次只能工作一行,所以它找不到分散在行中的SELECT语句。

第二个问题是,您使用的正则表达式不能处理SELECT和FROM之间可能出现的复杂性-特别是省略逗号、句号(句号)和空白,还包括引号和引号,以及可以在引号中出现的任何内容。

我可能会使用基于perl的解决方案,让perl一次读取“段落”,并对此应用正则表达式。缺点是必须处理递归搜索-当然,也有一些模块可以这样做,包括核心模块。档案:查找.

在大纲中,对于单个文件:

$/ = "\n\n";    # Paragraphswhile (<>){
     if ($_ =~ m/SELECT.*customerName.*FROM/mi)
     {
         printf file name
         go to next file     }}

它需要包装到一个子文件中,然后由File:Find方法调用。


查看完整回答
反对 回复 2019-07-10
  • 3 回答
  • 0 关注
  • 691 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信