grep を使用した最長共通部分文字列

grep を使用した最長共通部分文字列

私はdictionary.txtという巨大なテキストファイルを持っています。そこには次のようなエントリがあります。

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

別のファイルには、変数名の一部としてこれらの略語のいくつかを使用しているプログラムのソースがあります。変数名は、次のように上記のエントリを使用することがよくあります。

     Facilitator.TMP_ABC_SEQ_NUM 

したがって、grep を使用して TMP_ABC_SEQ_NUM を単純に検索することはできません。一致するものが返されないためです。ただし、変数名の最後の部分 (「ABC_SEQ_NUM」) は、実際にはテキスト ファイルに存在します。

私はこう言いたいのです

      grep (longest match for) TMP_ABC_SEQ_NUM in dictionary.txt

マッチを返すように

      ABC_SEQ_NUM

このようなコマンドはどのように記述するのでしょうか?

答え1

これは最初から一致しようとします:

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

これは、どこから始まるかに関係なく、最も長いシーケンスを検索します。

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 

要件: bash のようなシェル (こちらから入手可能)sh.exe、grep、sed、awk、bc、cat、tac、rev、col、cut などの多くの GNU ユーティリティのネイティブ win32 ポート。

答え2

一致するまで先頭から文字列を短くする、可能なアプローチ:

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

答え3

これを逆に見ていただけますか? を探すのではなくTMP_ABQ_SEQ_NUM、ソース ファイル内dictionary.txtの各行の最初のフィールドdictionary.txt(ABQ_SEQ_NUM) を探してみませんか?

この場合、次の方法が機能するはずです

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

上記のスクリプトに、dictionary.txt に存在するシーケンスを確認するファイルの名前を渡します。これがご希望どおりでない場合はお詫び申し上げます。

関連情報