別のファイル範囲内で、あるファイルの値を見つけて親値を選択します。

別のファイル範囲内で、あるファイルの値を見つけて親値を選択します。

A、B 2つのファイルがあります。ファイルAには4つの列と600,000の行があります。ファイルBには4つの列と5000の行があります。例:

ファイル-A:

ENSB1 1 12245 0.53 0.002
ENSB2 1 13400 0.27 0.0003
ENSB3 1 14780 0.13 0.00001
ENSB4 1 15201 0.33 0.9
ENSB5 2 56259 0.70 0.0002
ENSB6 2 57000 0.42 0.00004
ENSB7 2 58200 0.50 0.5

ファイル-B:

1 12000 15000 G1
1 14000 16000 G2
2 56000 59000 G3

File-Bの最初の行を選択したいと思います。次に、ファイルAの列3の値がファイルBの列2と3の値の範囲内にあるように、ファイルAの複数行を識別しようとします。ファイルAの2列もファイルBの2列と3列の値の範囲に属し、ファイルBの1列の値は一致します。 File-Aの複数の行が上記の条件を満たすと予想しています。上記の基準に従って複数の行が識別されると、ファイルAの対応する行のうち5列の最も低い値が選択され、ファイルBの対応する行の新しい列に書き込まれます。 File-Bのすべての行に対してこの手順を繰り返します。

予想される新しいファイル:

1 12000 15000 G1 0.00001
1 14000 16000 G2 0.00001
2 56000 59000 G3 0.00004

私はLinuxコマンドを初めて学ぶ人ですが、誰でも助けていただければと思います。

ベストアンサー1

努力する

awk 'NR==FNR   {Line[FNR] = $0           # first file processing
                Cat[FNR]  = $1
                Min[FNR]  = $2
                Max[FNR]  = $3
                Low[FNR]  = 1E10         # initialize to high number so first value from file2 will be lower
                ML        = FNR
                next
               }
                                         # second file processing; if same Category and $3 between Min and Max, and $5 lower than before one, keep $5

               {for (i=1; i<=ML; i++)  if ($2 == Cat[i] &&
                                           $3 >= Min[i] &&
                                           $3 <= Max[i] &&
                                           $5 <  Low[i]) Low[i] = $5
               }
END                     {for (i=1; i<=ML; i++) print Line[i], Low[i]
                        }
' File-B File-A
1 12000 15000 G1 0.00001
1 14000 16000 G2 0.00001
2 56000 59000 G3 0.00004

多くの説明は必要ありません。最初のファイル(NR == FNR)から始めて、カテゴリと範囲/境界の値を維持し、最初の読み取りの実際の値が低くなるようにLow配列要素を設定します。 2番目のファイルを処理するときは、上記のデータセットを繰り返します。新しく読み取ったレコードがアイテムと同じカテゴリを持ち、$ 3がMinとMaxの間にあり、$ 5が以前に取得したレコードよりも低い場合は、$ 5を配列に保持しますLow。このENDセクションでは、記録された行と得られたLow値を標準出力として印刷します。

おすすめ記事