awk 動的文字列の一致

awk 動的文字列の一致

2つのファイルがあります。 (a)名前をインポートするファイルと名前を含むファイル、および(b)名前を一致させ、その前後の2つの単語をインポートしたい実際のファイル。

最初のファイルのスナップショット

Ito 65482.txt
David Juno Ilrcwrry Hold 73586.txt
David Jones 73586.txt
Jacob FleUchbautr 73586.txt

名前は、上記のようにスペースで区切られた文字列です。

ファイル65482.txtのスナップショット(壊れたOCRテキストを含む)

nose just brnukiiitt tip tinwallfin the golden 
path of Ito etmlmbimiiit tlmmgli the trees 
Butt It as tie not intra and plcturosiiiicness 
limit wo were of m that is not altogether We 
and hunting and llslilng In plenty anti lit lIly 

希望の出力フォーマット

Ito path of etmlmbimiiit tlmmgli 

つまり、ゲームの前とゲーム後の2つの単語です。

#!/bin/bash
fPath='/Users/haimontidutta/Research/IIITD/Aayushee/Code/Source-Code/Thesis/src/ReputedPersonDetection/data/OutputofNERFinal_v1a.txt'
echo "Enter Script"

while IFS=' ' read -ra arr
do 
 fname="${arr[${#arr[@]}-1]}"
 #echo $fname
 name=""
 for((idx=0; idx<$[${#arr[@]}-1]; ++idx))
 do
  name=$name" ${arr[idx]}"
 done
 #echo $name 
 filepath='/Users/haimontidutta/Research/IIITD/Aayushee/Code/Source-Code/Thesis/src/ReputedPersonDetection/data/final/'$fname
 #echo $fName
 #echo $filepath

 #Extract window around name
 awk -v nm="$name" '{
     for(i=1;i<=NF;i++)
     {
       #print $i 
       if($i~$nm)
       {
        print nm OFS  $(i-2) OFS $(i-1) OFS $(i+1) OFS $(i+2); exit;
      }}}' $filepath
done < $fPath

名前とファイルパスを抽出できますが、awkステートメントで名前の動的一致が失敗し、ウィンドウを取得できません。

どうすればいいですか?

ベストアンサー1

配列の配列にGNU awkを使用する:

$ cat tst.awk
NR==FNR {
    file = $NF
    name = $1 (NF>2 ? " " $2 : "")
    if ( !(file in file2names) && ((getline line < file) > 0) ) {
        close(file)
        ARGV[ARGC++] = file
    }
    file2names[file][name]
    next
}
{
    $0 = " " $0 " "
    for (name in file2names[FILENAME]) {
        if ( pos = index($0," "name" ") ) {
            split(substr($0,1,pos),bef)
            split(substr($0,pos+length(name)+1),aft)
            print name, bef[1], bef[2], aft[1], aft[2]
        }
    }
}

$ awk -f tst.awk file
Ito path of etmlmbimiiit tlmmgli

最初の1つまたは2つ(以下の説明を参照)だけでなく、「file」のすべてのファイル名以前の文字列を名前の一部として含めるには、次のように変更します。

name = $1 (NF>2 ? " " $2 : "")

これに対してゴークはこう述べた。

name = gensub(/\s+\S+$/,"",1)

またはいずれにせよ:

name = $0
sub(/ +[^ ]+$/,"",name)

他のawkと同様に、ファイル名をスペースで区切られた文字列として保存します。たとえば、次の手順file2names[file][name]を実行するfile2names[file] = (file in file2names ? file2names[file] FS : "") nameのではなく、ループを実行する前に分割します。for (name in file2names[file])split(file2names[FILENAME],names); for (name in names)

上記の入力はfile例の最初のファイルにすぎません。

おすすめ記事