Subcadena común más larga usando grep

Subcadena común más larga usando grep

Tengo un archivo de texto enorme llamado diccionario.txt con entradas como

    ABC_SEQ_NUM This represents....
    ABC_RANK This represents....
    ABC_BSC_ID This represents...
    PQR_TA_DATE_AF This represents...
    XYZ_C_ID This represents...

En otro archivo, tengo el código fuente de un programa que utiliza algunas de estas abreviaturas como parte de sus nombres de variables. Los nombres de las variables suelen utilizar las entradas anteriores de la siguiente manera

     Facilitator.TMP_ABC_SEQ_NUM 

Por lo tanto, no puedo simplemente buscar TMP_ABC_SEQ_NUM usando grep, porque no arrojaría ninguna coincidencia. Sin embargo, la última parte del nombre de la variable ("ABC_SEQ_NUM") está realmente presente en el archivo de texto.

Entonces me gustaría decir algo como

      grep (longest match for) TMP_ABC_SEQ_NUM in dictionary.txt

Para que le devolviera el partido por

      ABC_SEQ_NUM

¿Cómo escribir tal comando?

Respuesta1

Esto intentaría hacer coincidir desde el principio:

t=TMP_ABC_SEQ_NUM
for n in $(seq 0 ${#t})
do
  grep ${t:n} dictionary.txt && break
done

Esto busca la secuencia más larga, sin importar dónde comience:

for len in $(seq ${#t} -1 3)
do
   for start in $(seq 0 $((${#t}-len)))
   do
       grep ${t:start:len} dictionary.txt && break 2
   done
done 

requisito: Un shell tipo bash, disponible aquí:Puertos nativos win32 de muchas utilidades GNU, como sh.exe, grep, sed, awk, bc, cat, tac, rev, col, cut, ...

Respuesta2

Un posible enfoque, acortar la cuerda desde la cabeza hasta que coincida:

#!/bin/sh
string="TMP_ABQ_SEQ_NUM"
while ! grep "$string" dictionary.txt; do 
  # remove the shortest leading string ending with "_"
  string="${string#*_}"
done

Respuesta3

¿Podrías revertir la forma en que estás viendo esto? En lugar de buscar TMP_ABQ_SEQ_NUMen dictionary.txt, ¿no podría buscar el primer campo para cada línea en dictionary.txt(ABQ_SEQ_NUM) en el archivo fuente?

Si este es el caso, lo siguiente debería funcionar

#!/bin/bash
for i in $(awk '{print $1}' dictionary.txt) do
    grep $i $1
done

Pase al script anterior el nombre del archivo que desea verificar para ver las secuencias presentes en diccionario.txt. Disculpas si esto no es lo que querías.

información relacionada