Grep / Regex跨越多条线上的固定模式匹配,具有匹配的特殊条件

时间:2013-12-19 00:05:57

标签: regex grep pcre

我有一个问题,我需要在许多文件中识别每个问题。根据跨多行的模式确定出现次数。

在我的情况下,我试图识别具有前导空格的文字,包含多个连续的空格字符,或者前面是一组已知的小字(例如'或','和'等)。文字由单引号决定。但是我只对文字感兴趣,其中前面的四行包含单词“LITERAL”。

以下是文件内容的一些示例:

EXEC LITERAL
    LEVEL
    NAME
    LENGTH
    VALUE (' Foo')
END EXEC

EXEC LITERAL
    LEVEL
    NAME
    VALUE ('Foo  Bar')
END EXEC

EXEC LITERAL
    LEVEL
    NAME
    VALUE ('Bar Foo')
END EXEC

EXEC LITERAL
    LEVEL
    NAME
    VALUE ('Foo')
END EXEC

EXEC LITERAL
    LEVEL
    NAME
    LENGTH
    VALUE ('or Bar')
END EXEC

EXEC DEFINITION
    LEVEL
    NAME
    LENGTH
    VALUE ('Bar')
END EXEC

在上面的例子中,我希望输出识别文件并列出'Foo','Foo Bar'和'或Bar'的出现次数。请注意,不包括'Bar Foo',因为如果单个空格是单个空格,则可以接受用于分隔引号中的单词的任何空格。

我已经能够构造grep语句,允许我识别多个空格的实例,前导空格并包含一个小字(通过多个管道),但是我似乎无法使用grep来表示正则表达式。我在另一篇文章中提到过使用pcregrep来支持grep中的正则表达式。我很乐意这样做,但我有点迷失正则表达式使用。

到目前为止,我已经完成了以下命令:

pcregrep -M 'LITERAL.*\n.*\n.*\n.*\n.*VALUE.* ' test.txt

不幸的是它没有拿起'Foo Bar'的例子(因为4 x \ n我假设)。下一个拿起'Foo Bar'但没有拿起'或Bar':

pcregrep -M 'LITERAL.*\n.*\n.*\n.*\n.*VALUE.* ' test.txt

此外,当我使用较大的数据集进行测试时,如果它不符合上述模式(例如,它是与上述无关的另一个词的一部分),它将会选择LITERAL。我真的需要表达式来限制匹配给定的模式,忽略不构成上述示例模式的VALUE或LITERAL的实例。

如何解决这个问题的任何帮助都是最受欢迎的。

2 个答案:

答案 0 :(得分:2)

cat file.txt | awk '/LITERAL/ {print}' FS="\n" RS="" | grep -v "END"

您可以拥有END

的完整列表
 cat file.txt | awk '/LITERAL/ {print}' FS="\n" RS=""

答案 1 :(得分:0)

你可以 1.在\b前面指定单词边界LITERAL,以避免误报 2.而不是在正则表达式中修改换行符的数量,而是为.\n指定非贪婪的匹配

pcregrep   -M '\bLITERAL(?:(?!VALUE).|\n)*?VALUE[[:blank:]]*\('"'(?=.*[[:blank:]].*).*?'\)" file.txt