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
例の最初のファイルにすぎません。