【问题标题】:Grep/Regex matching across a fixed pattern across a multiple lines with special conditions on matching跨多行的固定模式的 Grep/Regex 匹配,具有特殊的匹配条件
【发布时间】:2014-01-07 09:30:48
【问题描述】:

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

在我的例子中,我试图识别具有前导空格、包含多个连续空格字符或前面有一组已知小词(例如“或”、“和”等)的文字。文字由单引号决定。但是,我只对其中四行包含“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' 和 'or Bar' 的出现。请注意,“Bar Foo”不包括在内,因为如果引号中用于分隔单词的任何空格是单个空格,则可以接受。

我已经能够构建 grep 语句,允许我识别多个空格、前导空格和包含一个小单词(通过多个管道)的实例,但是我似乎无法将 grep 用于正则表达式。我在另一篇文章中看到过使用pcregrep 来支持grep 中的正则表达式。我很高兴这样做,但我对使用的正则表达式有点迷茫。

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

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

不幸的是,它没有选择“Foo Bar”示例(因为我认为是 4 x \n)。下一个拿起'Foo Bar'但没有拿起'or Bar':

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

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

欢迎任何有关如何解决此问题的帮助。

【问题讨论】:

    标签: regex grep pcre


    【解决方案1】:
    cat file.txt | awk '/LITERAL/ {print}' FS="\n" RS="" | grep -v "END"
    

    您可以使用 END 获得完整列表

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

    【讨论】:

    • 虽然如果文件只包含我的问题中的值,那么当文件中包含其他数据时它不起作用。我试图在一个充满其他东西的文件中从我的问题中找到模式。如果不清楚,我深表歉意。
    【解决方案2】:

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

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

    【讨论】:

    • 差不多了,但它正在接收“Foo”。是否可以在第一个单引号后有空格或与 VALUE 在同一行的单引号之间有两个空格的地方进行修改?这样它会忽略“Foo”并满足我想要实现的目标。
    • @Metalskin,修订版检查VALUE 之后的括号之间是否存在至少一个空格。不像你需要的那样具体,但正如你所看到的那样,正则表达式正在失控......
    • 非常接近!最后一个问题(这是我的错,因为它不在给出的示例中),如果我有“Foo Bar”,那么它就会被拾起。我需要排除单引号之间出现单个空格但不是引号内的前导或尾随空格的那些(如果有意义的话)。我会更新我的问题,以便更清楚。啊,刚刚看到你说它不像我需要的那样具体。如果你没有时间,我会试着用正则表达式来整理它。
    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    相关资源
    最近更新 更多