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