あるファイルの配列で値を見つけ、別のファイルで値を見つけて、その値を使用して別のファイルを見つけて変数に設定します。

あるファイルの配列で値を見つけ、別のファイルで値を見つけて、その値を使用して別のファイルを見つけて変数に設定します。

だから、2つのファイルがあります。ファイル1は次のようになります。

RR1.out       RR2.out       RR3.out       RR4.out       RR5.out       RR6.out
45.7597       45.7646       45.4453       45.4448       45.2081       45.1785 
55.5468       55.5269       55.3789       55.3598       55.4377       55.4591 
51.4768       51.4792       51.6955       51.6972       51.5128       51.5245 
54.9851       54.9957       54.9617       54.9688       54.9465       54.9579 
45.4459       45.4623       46.1614       46.1679       46.0906       46.0488 

ファイル2は次のようになります。

 file Gibbs kcal rel pop weighted
 RR2.out    -1752.142111    -1099486.696073  0.000000 1.0000 0.4591
 RR1.out    -1752.141887    -1099486.555511  0.140562 0.7890 0.3622
 RR4.out    -1752.140564    -1099485.725315  0.970758 0.1947 0.0894
 RR3.out    -1752.140319    -1099485.571575  1.124498 0.1502 0.0689
 RR5.out    -1752.138532    -1099484.450215  2.245858 0.0227 0.0104
 RR6.out    -1752.138493    -1099484.425742  2.270331 0.0218 0.0100

スクリプトはファイル 1 の列 1 から最初の値を取得し、ファイル 2 の列 1 でその値を探し、その値と同じ行にあるファイル 2 の列 6 で値を探し、ファイル 1 の列 1の残りの数字にその値を掛けて新しいファイルとして印刷し、列が足りなくなるまで繰り返します。その後、すべての新しいデータをファイル1(RR1.outなど)と同じタイトルの下にマージする必要があります。

たとえば、最初に見つかった値はRR1.outで、ファイル2、列1、行3にあり、行3、列6の値は0.3622です。したがって、file1のcolumn1に残っている値に0.3622を掛けて新しいファイルに印刷する必要があります。

私が使っているスーパーコンピュータはさまざまな言語で動作するかもしれませんが、私が最も慣れている言語はbashとawkです。 Pythonはスーパーコンピュータでも実行できます。

どこから始めるべきかについてのアドバイスをいただきありがとうございます。私はawkの配列関数のいくつかを使って値を照会することができると思いますが、ドキュメント間で変数を転送する方法がわかりません。

要件に応じて、出力は次のようになります。

   RR1.out        RR2.out        RR3.out       RR4.out       RR5.out       RR6.out
   16.57416       21.01052       3.13118       4.06276       0.47016       0.45178
   20.11905       25.49239       3.81560       4.94916       0.57655       0.55459
   18.64489       23.63410       3.56181       4.62172       0.53573       0.51524
   19.91560       25.24852       3.78686       4.91421       0.57144       0.54957
   16.46050       20.87174       3.18052       4.12741       0.47934       0.46048

最終スクリプトは、30列と100行以上のfile1の大容量データを処理できる必要があります。 file1の列と行数は、最大100列と100行まで可変です。

答え1

多様性のために、主に浮動小数点演算を使用するbashソリューションがありますbc

#!/usr/bin/env bash

# r is an associative array of weights, indexed by column name

declare -A r

source <(awk '{ print "r[\"" $1 "\"]=" $6}' <( tail +2 file2))

hdr=

while read line
do
        if ! [ $hdr ]
        then
                hdr=($line)
                set -- $line
                for h do
                        printf '%-12s ' "$h"
                done
                printf '\n'
        else
                set -- $line
                for h in ${hdr[@]}
                do
                        coef=${r[$h]}
                        printf '%-11.5f  ' \
                            $(bc <<< "scale=6; $1 * $coef")
                        shift
                done
                printf '\n'
        fi

done < file1

6x5サンプル出力:

RR1.out      RR2.out      RR3.out      RR4.out      RR5.out      RR6.out      
16.57416     21.01053     3.13118      4.06277      0.47016      0.45179      
20.11905     25.49240     3.81561      4.94917      0.57655      0.55459      
18.64490     23.63410     3.56182      4.62173      0.53573      0.51524      
19.91560     25.24852     3.78686      4.91421      0.57144      0.54958      
16.46050     20.87174     3.18052      4.12741      0.47934      0.46049      

答え2

100x100ファイルはそれほど大きくないので、特別な処理は必要ありません。各列ごとに異なる出力ファイルを作成し、貼り付けを使用してそれらを結合することを想像してきましたが、小さいファイルの場合はこれは必要なく、値を配列に保存するだけです。

$ cat tst.awk
BEGIN { OFS = "\t" }
NR==FNR {
    key2mult[$1] = $NF
    next
}
FNR==1 {
    for (colNr=1; colNr<=NF; colNr++) {
        colNr2mult[colNr] = key2mult[$colNr]
        printf "%s%s", $colNr, (colNr<NF ? OFS : ORS)
    }
    next
}
{
    for (colNr=1; colNr<=NF; colNr++) {
        vals[FNR,colNr] = $colNr
    }
}
END {
    for (rowNr=2; rowNr<=FNR; rowNr++) {
        for (colNr=1; colNr<=NF; colNr++) {
            printf "%.05f%s", vals[rowNr,colNr] * colNr2mult[colNr], (colNr<NF ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk file2 file1
RR1.out RR2.out
16.57416        21.01053
20.11905        25.49240
18.64490        23.63410

上記はこの入力で実行されます。

$ tail -n +1 file1 file2
==> file1 <==
RR1.out       RR2.out
45.7597       45.7646
55.5468       55.5269
51.4768       51.4792

==> file2 <==
file Gibbs weighted
 RR2.out    -1752.142111    0.4591
 RR1.out    -1752.141887    0.3622
 RR4.out    -1752.140564    0.0894

新しいサンプル入力を使用する:

$ awk -f tst.awk file2 file1
RR1.out RR2.out RR3.out RR4.out RR5.out RR6.out
16.57416        21.01053        3.13118 4.06277 0.47016 0.45178
20.11905        25.49240        3.81561 4.94917 0.57655 0.55459
18.64490        23.63410        3.56182 4.62173 0.53573 0.51525
19.91560        25.24853        3.78686 4.91421 0.57144 0.54958
16.46050        20.87174        3.18052 4.12741 0.47934 0.46049

$ awk -f tst.awk file2 file1 | column -s$'\t' -t
RR1.out   RR2.out   RR3.out  RR4.out  RR5.out  RR6.out
16.57416  21.01053  3.13118  4.06277  0.47016  0.45178
20.11905  25.49240  3.81561  4.94917  0.57655  0.55459
18.64490  23.63410  3.56182  4.62173  0.53573  0.51525
19.91560  25.24853  3.78686  4.91421  0.57144  0.54958
16.46050  20.87174  3.18052  4.12741  0.47934  0.46049

関連情報