別のファイルで指定された範囲に基づいて複数の列行を選択します。

別のファイルで指定された範囲に基づいて複数の列行を選択します。

2つのファイルがあります。

ファイル1

ST4.03ch10 56000001 56500000
ST4.03ch11 34500001 35000000
ST4.03ch04 54500001 55000000
ST4.03ch12 500001 100

ファイル2

ST4.03ch12 56014301 56019800 0.163 遺伝子 5.5
ST4.03ch12 56022401 56025300 0.419 遺伝子 2.9
ST4.03ch12 671201 803530
1 00 1 遺伝子 5.3 ST4.03ch12 671201 803500
1 遺伝子 5.0
ST4.03ch12 447401 449500 0.038 遺伝子 8.5
ST4 。 03ch12 671201 803500 1 遺伝子 9.5

編集:前のサンプルデータに基づいて生成されたコードは実際のデータとうまく機能しないため、ここに実際のデータのいくつかを追加しました。

次の3つの基準に基づいて、file1の行の1つに一致するfile2の行を選択して印刷しようとしています。

1. col1 of file2 = col1 of file1;  
2. col2 of file2 >/= col2 of file1, and  
3. col3 of file2 </= col3 of file1

私がしたいことは:ファイル1のcol1に識別子(ST4.03chXX)が含まれ、col2(開始)とcol3(終了)に対応する調整範囲が含まれており、ファイル2で項目を探しています。
1)識別子colAの
開始座標と終了座標(colBとcolC)は、ファイル1の対応する識別子の範囲内のファイル1と2の識別子と一致します。

予想出力:

ST4.03ch12 671201 803500 1 遺伝子 5.5
ST4.03ch12 671201 803500 1 遺伝子 5.3 ST4.03ch12 671201
803500 1 遺伝子 5.0 ST4.03ch20 15 67

実際のファイル(特にファイル2)はかなり大きいので、aを使って作業を完了したいのですが、awk必要に応じてループが機能します。

ベストアンサー1

次のように試すことができます。

awk 'NR==FNR{z[$1]?z[$1]=z[$1]"|"$2"|"$3:z[$1]=$2"|"$3;next}
{if ($1 in z){l=split(z[$1], k, "|");
{for (i=1;i<l;i+=2){if ($2>=k[i] && $3<=k[i+1]){print}}}}}' file1 file2

これを読みfile1、2番目と3番目のフィールドをaで連結|し、それを配列z(最初のフィールドにインデックス付けされている)に保存し、最初のフィールドがあるかどうかをfile2読み、確認します。zもしそうなら、z[1st field]行を分割して|印刷k[i]します。iフィールド2>=k[i]とフィールド3の場合、各奇数値<=k[i+1]

おすすめ記事