首页 > 解决方案 > grep 文件中的模式,打印模式而不是匹配的字符串

问题描述

我想使用包含正则表达式的文件中的模式进行 grep。当模式匹配时,它会打印匹配的字符串而不是模式。我怎样才能得到模式而不是匹配的字符串?

模式.txt

Apple (Ball|chocolate|fall) Donut
donut (apple|ball) Chocolate
Donut Gorilla Chocolate
Chocolate (English|Fall) apple gorilla
gorilla chocolate (apple|ball)
(ball|donut) apple

字符串.txt

apple ball Donut
donut ball chocolate
donut Ball Chocolate
apple donut
chocolate ball Apple

这是 grep 命令

grep -Eix -f pattern.txt strings.txt

此命令从 strings.txt 打印匹配的字符串

apple ball Donut
donut ball chocolate
donut Ball Chocolate

但我想从 pattern.txt 中找到用于匹配的模式

Apple (Ball|chocolate|fall) Donut
donut (apple|ball) Chocolate

pattern.txt 可以是小写、大写、符合正则表达式和不符合正则表达式、自由数量的单词和正则表达式元素。除了括号和管道之外,没有其他类型的正则表达式。

我不想使用循环来读取 pattern.txt 每一行到 grep,因为它很慢。有没有办法在 grep 命令中打印模式文件的哪个模式或行号?或者 grep 以外的任何其他命令都可以完成这项工作不会太慢?

标签: bashawkgrep

解决方案


使用grep我不知道但使用 GNU awk:

$ awk '
BEGIN { IGNORECASE = 1 }      # for case insensitivity
NR==FNR {                     # process pattern file
    a[$0]                     # hash the entries to a
    next                      # process next line
}
{                             # process strings file
    for(i in a)               # loop all pattern file entries
        if($0 ~ "^" i "$") {  # if there is a match (see comments)
            print i           # output the matching pattern file entry
            # delete a[i]     # uncomment to delete matched patterns from a
            # next            # uncomment to end searching after first match
        }
}' pattern strings

输出:

D (A|B) C

对于strings脚本中的每一行,将循环每一pattern行以查看是否有多个匹配项。由于区分大小写,只有一个匹配项。例如,您可以使用 GNU awk 的IGNORECASE.

此外,如果您希望每个匹配的一个模式文件条目输出一次,您可以a在第一次匹配后删除它们:delete a[i]print. 这也可能会给您带来一些性能优势。


推荐阅读