저는 아래와 같이 8개의 필드를 포함하는 세 개의 유사한 텍스트 파일로 작업하고 있습니다.
File1:
145794 MEG -0.249553181556742 10.7024481844394 -2.66596894783271 0.00786178413495372 0.0601441357290167 -2.83690413867182
144476 ACK 0.290866506987197 8.80253427197157 2.61876968039967 0.00902429557487308 0.0658077662524982 -2.9436012186193
213406 ANX -0.396398224155449 2.29892473132668 -2.67676795263515 0.00761548692081231 0.0589487734598402 -3.08353414541367
File2:
145794 MEG -0.287372579587733 9.41247425082302 -1.97898175477022 0.0490956252910287 0.309158729905081 -4.08090215553766
144476 ACK 0.298963990141891 6.98503289865222 1.45624070508412 0.146786315195169 0.492695221406182 -4.92059721623638
144161 ZCH -0.0427538540851567 9.7901544903037 -1.06263504958352 0.288330305382714 0.545733380330329 -5.69279245581735
File3:
145794 MEG -0.0565314859334139 11.3691862642502 -0.581110824476088 0.56158942073398 0.792421821608773 -5.90344886517337
144476 ACK 0.25574693016845 9.21536363194302 1.89547789943679 0.0589622388458051 0.247543472790285 -4.34643638570199
144161 ZCH -0.0618203872359407 9.77324184266448 -1.14042457462774 0.254992692808188 0.539040584775996 -5.42726538436031
첫 번째 및 두 번째 필드의 값과 일치하는 세 파일을 병합하고 싶으므로 내 코드는 다음과 같습니다.
awk '
FNR==1{
f++
}
f==1{
g[$1]=$0;
next
}
f==2{
if($1 in g) g[$1]=g[$1]"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8;
else g[$1]=$0
}
f==3{
if($1 in g) g[$1]=g[$1]"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8;
else g[$1]=$0
}
END{
for (i in g) print g[i]
}
' file1.txt file2.txt file3.txt > merged.txt
예상 출력:
145794 MEG -0.249553181556742 10.7024481844394 -2.66596894783271 0.00786178413495372 0.0601441357290167 -2.83690413867182 -0.287372579587733 9.41247425082302 -1.97898175477022 0.0490956252910287 0.309158729905081 -4.08090215553766 -0.0565314859334139 11.3691862642502 -0.581110824476088 0.56158942073398 0.792421821608773 -5.90344886517337
144476 ACK 0.290866506987197 8.80253427197157 2.61876968039967 0.00902429557487308 0.0658077662524982 -2.9436012186193 0.298963990141891 6.98503289865222 1.45624070508412 0.146786315195169 0.492695221406182 -4.92059721623638 0.25574693016845 9.21536363194302 1.89547789943679 0.0589622388458051 0.247543472790285 -4.34643638570199
213406 ANX -0.396398224155449 2.29892473132668 -2.67676795263515 0.00761548692081231 0.0589487734598402 -3.08353414541367
144161 ZCH -0.0427538540851567 9.7901544903037 -1.06263504958352 0.288330305382714 0.545733380330329 -5.69279245581735 -0.0618203872359407 9.77324184266448 -1.14042457462774 0.254992692808188 0.539040584775996 -5.42726538436031
하지만
g[$1]=g[$1]"\t"$3"\t"$4"\t"$5"\t"$6"\t"$7"\t"$8
너무 길어요. 좀 더 깔끔하게 교체할 수 있는 방법이 있나요?
답변1
cat
+awk
해결책:
cat file[123].txt \
| awk '{ k = $1 OFS $2 }
!(k in a){ keys[++c] = k }
{ a[k] = (a[k]? a[k] OFS : "") $3 OFS $4 OFS $5 OFS $6 OFS $7 OFS $8; }
END{
for (i=1; i<=c; i++) print keys[i], a[keys[i]]
}' OFS='\t'
k = $1 OFS $2
-$1
첫 번째 필드와 두 번째 필드로 구성된 키$2
!(k in a){ keys[++c] = k }
- 초기 순서로keys
그룹 키를 포함하는 배열 입니다.k
a[k] = (a[k]? a[k] OFS : "") $3 OFS $4 ...
- 특정 그룹과 관련된 모든 필수 필드 값을 캡처/추가k
산출:
145794 MEG -0.249553181556742 10.7024481844394 -2.66596894783271 0.00786178413495372 0.0601441357290167 -2.83690413867182 -0.287372579587733 9.41247425082302 -1.97898175477022 0.0490956252910287 0.309158729905081 -4.08090215553766 -0.0565314859334139 11.3691862642502 -0.581110824476088 0.56158942073398 0.792421821608773 -5.90344886517337
144476 ACK 0.290866506987197 8.80253427197157 2.61876968039967 0.00902429557487308 0.0658077662524982 -2.9436012186193 0.298963990141891 6.98503289865222 1.45624070508412 0.146786315195169 0.492695221406182 -4.92059721623638 0.25574693016845 9.21536363194302 1.89547789943679 0.0589622388458051 0.247543472790285 -4.34643638570199
213406 ANX -0.396398224155449 2.29892473132668 -2.67676795263515 0.00761548692081231 0.0589487734598402 -3.08353414541367
144161 ZCH -0.0427538540851567 9.7901544903037 -1.06263504958352 0.288330305382714 0.545733380330329 -5.69279245581735 -0.0618203872359407 9.77324184266448 -1.14042457462774 0.254992692808188 0.539040584775996 -5.42726538436031