首页 > 解决方案 > 将两个列表中的行与一个列表中的通配符匹配

问题描述

我有两个列表,其中一个包含通配符(在本例中由 * 表示)。我想比较这两个列表并创建匹配的输出,每个通配符 * 代表一个字符。

例如:

文件 1

123456|Jane|Johnson|Pharmacist|janejohnson@gmail.com
09876579|Frank|Roberts|Butcher|frankie1@hotmail.com
092362936|Joe|Jordan|Joiner|joe@joesjoinery.com
928|Bob|Horton|Farmer|bhorton@farmernews.co.uk

文件 2

1***6|Jane|Johnson|Pharmacist|janejohnson@gmail.com
09876579|Frank|Roberts|Butcher|f**1@hotmail.com
092362936|Joe|Jordan|J*****|joe@joesjoinery.com
928|Bob|Horton|Farmer|b*****n@f*********.co.uk

输出

092362936|Joe|Jordan|Joiner|joe@joesjoinery.com
928|Bob|Horton|Farmer|bhorton@farmernews.co.uk

解释

前两行不被视为匹配,因为 *s 的数量不等于第一个文件中显示的字符数。后两者是,因此它们被添加到输出中。

我试图找出在 AWK 中执行此操作并使用 Join 的方法,但我什至不知道有什么方法可以开始尝试实现这一目标。任何帮助将不胜感激。

标签: joinawksedgrep

解决方案


$ cat tst.awk
NR==FNR {
    file1[$0]
    next
}
{
    # Make every non-* char literal (see https://stackoverflow.com/a/29613573/1745001):
    gsub(/[^^*]/,"[&]")  # Convert every char X to [X] except ^ and *
    gsub(/\^/,"\\^")     # Convert every ^ to \^

    # Convert every * to .:
    gsub(/\*/,".")

    # Add line start/end anchors
    $0 = "^" $0 "$"

    # See if the current file2 line matches any line from file1
    # and if so print that line from file1:
    for ( line in file1 ) {
        if ( line ~ $0 ) {
            print line
        }
    }
}

$ awk -f tst.awk file1 file2
092362936|Joe|Jordan|Joiner|joe@joesjoinery.com
928|Bob|Horton|Farmer|bhorton@farmernews.co.uk

推荐阅读