Encontre o prefixo correspondente mais longo no arquivo?

2

Por exemplo, o arquivo a.txt :

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

Dê entrada e os resultados esperados são:

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

Isso é possível usando apenas comandos do shell ou grep , sed , awk , etc.?

    
por Xiè Jìléi 13.12.2010 / 17:18

3 respostas

3

Uma maneira de fazer isso é reverter um pouco a idéia de qual é a entrada e usar a.txt como os padrões para procurar e o que você está chamando de "entrada" (eu chamarei de "arquivo2") para ser o que é pesquisado em :

grep -o -f a.txt file2

ou

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

Estes não produzirão nada para "/ dog", embora a versão echo tenha um código de retorno diferente de zero.

Editar:

Isso corresponderá mais de perto à saída solicitada:

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

Você pode forçar os padrões de pesquisa a começar no início da linha assim:

grep -o -f <(sed 's/^/^/' a.txt) file2
    
por 13.12.2010 / 20:38
1

Parece um trabalho para Perl, então aqui está uma solução para o awk. Minimamente testado.

#!/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)"; }
}' "$@"
    
por 14.12.2010 / 00:36
0

Um script de shell simples deve fazer o trabalho:

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

Você pode usá-lo como:

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

e imprimirá a correspondência mais longa da consulta /abc/dog encontrada no arquivo a.txt, ou seja, /abc/d

    
por 13.12.2010 / 21:33

Tags