한 파일의 배열에서 값을 찾고, 다른 파일에서 값을 찾은 다음, 해당 값을 사용하여 다른 파일을 찾아 변수에 설정합니다.

한 파일의 배열에서 값을 찾고, 다른 파일에서 값을 찾은 다음, 해당 값을 사용하여 다른 파일을 찾아 변수에 설정합니다.

그래서 두 개의 파일이 있습니다. 파일 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

관련 정보