Längste gemeinsame Teilzeichenfolge mit grep

Längste gemeinsame Teilzeichenfolge mit grep

Ich habe eine riesige Textdatei namens dictionary.txt mit Einträgen wie

    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...

In einer anderen Datei habe ich den Quelltext eines Programms, das einige dieser Abkürzungen als Teil seiner Variablennamen verwendet. Die Variablennamen verwenden oft die obigen Einträge wie folgt

     Facilitator.TMP_ABC_SEQ_NUM 

Ich kann also nicht einfach mit grep nach TMP_ABC_SEQ_NUM suchen, da dies keine Übereinstimmung zurückgeben würde. Der letzte Teil des Variablennamens („ABC_SEQ_NUM“) ist jedoch tatsächlich in der Textdatei vorhanden.

Ich würde also gerne etwas sagen wie

      grep (longest match for) TMP_ABC_SEQ_NUM in dictionary.txt

Damit es das Spiel zurückgibt für

      ABC_SEQ_NUM

Wie schreibt man einen solchen Befehl?

Antwort1

Dies würde versuchen, von Anfang an eine Übereinstimmung herzustellen:

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

Es wird nach der längsten Sequenz gesucht, unabhängig davon, wo sie beginnt:

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 

Voraussetzung: Eine Bash-ähnliche Shell, verfügbar hier:native Win32-Ports vieler GNU-Dienstprogramme, wie sh.exe, grep, sed, awk, bc, cat, tac, rev, col, cut, …

Antwort2

Ein möglicher Ansatz, den String vom Kopf her zu kürzen bis er passt:

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

Antwort3

Könnten Sie Ihre Sichtweise umkehren? Anstatt nach TMP_ABQ_SEQ_NUMin zu suchen dictionary.txt, könnten Sie nicht nach dem ersten Feld für jede Zeile in dictionary.txt(der ABQ_SEQ_NUM) in der Quelldatei suchen?

Wenn dies der Fall ist, sollte Folgendes funktionieren

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

Übergeben Sie dem obigen Skript den Namen der Datei, die Sie auf in dictionary.txt vorhandene Sequenzen prüfen möchten. Bitte entschuldigen Sie, wenn dies nicht das ist, was Sie wollten.

verwandte Informationen