2

Например, файл a.txt:

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

Введите входные данные и ожидаемые результаты:

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

Возможно ли это, используя только команды оболочки или grep , sed , awk и т.д.?

3 ответа3

3

Один из способов сделать это - несколько изменить представление о том, что является вводом, и использовать a.txt в качестве шаблонов для поиска, и то, что вы называете "вводом" (я назову "file2"), чтобы быть тем, что ищется в:

grep -o -f a.txt file2

или же

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

Они ничего не выведут для "/dog", хотя версия echo будет иметь ненулевой код возврата.

Редактировать:

Это будет более точно соответствовать вашему запросу:

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
1

Похоже, работа для 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)"; }
}' "$@"
0

Простой скрипт оболочки должен сделать эту работу:

#!/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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .