在文件中查找最长匹配的前缀?

在文件中查找最长匹配的前缀?

例如,文件a.txt

/abc
/abc/def
/abc/xyz
/abcd
/fghi

给出的输入和预期结果是:

/abc/dog     => /abc
/abc/def12   => /abc/def
/dog         => (NONE)

仅使用 shell 命令或grepsedawk等等可以实现吗?

答案1

一种方法是稍微反转一下输入的概念,并将其用作a.txt要搜索的模式,而你所说的“输入”(我称之为“file2”)就是要搜索的内容

grep -o -f a.txt file2

或者

echo "/abc/dog" | grep -o -f a.txt

echo尽管该版本将具有非零的返回代码,但这些不会为“/dog”输出任何内容。

编辑:

这将更紧密地匹配您请求的输出:

while read -r line
do
    match=$(echo "$line" | grep -of a.txt)
    match=${match:-(NONE)}
    printf "%-12s => %s\n" "$line" "$match"
done < file2

您可以强制搜索模式从行首开始,如下所示:

grep -o -f <(sed 's/^/^/' a.txt) file2

答案2

听起来像是 Perl 的工作,所以这里有一个 awk 解决方案。经过最低限度的测试。

#!/bin/sh
prefixes_file=$1
shift
awk -vprefixes_file="$prefixes_file" '
BEGIN {
    while (getline <prefixes_file) { ++prefixes[$0]; }
}
{
    for (n = length; n >= 0; --n) {
        if (prefixes[substr($0,1,n)]) {
            print $0, "=>", substr($0,1,n);
            break;
        }
    }
    if (n == -1) { print $0, "=>", "(NONE)"; }
}' "$@"

答案3

一个简单的 shell 脚本就可以完成这个工作:

#!/bin/sh

query=$1
file=$2

for i in $(seq 1 ${#query})
do
    current_query=$(echo $query | cut -b1-$i)
    grep -q "$current_query" "$file" || break;
    longest_match=$current_query
done

echo "$longest_match"

你可以像这样使用它:

longest_match.sh '/abc/dog' a.txt

它将打印/abc/dog在文件 a.txt 中找到的查询的最长匹配,即/abc/d

相关内容