从一个文件中的数组查找值,在另一个文件中查找值,然后使用该值查找另一个文件并将其设置为变量

从一个文件中的数组查找值,在另一个文件中查找值,然后使用该值查找另一个文件并将其设置为变量

所以我有两个文件,文件 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

最终脚本需要能够处理 file1 中超过 30 列和 100 行的大量数据。 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

相关内容