だから、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