필드 일치를 기반으로 두 파일의 특정 열을 병합합니다.

필드 일치를 기반으로 두 파일의 특정 열을 병합합니다.

제가 이 질문을 한 첫 번째 사람은 아니지만 제 코드는 여전히 작동하지 않습니다.

파일 1:

gi|1283| tRNAscan exon 87020 88058 . - . transcript_id "Parent=tRNA-Tyr5.r01";
gi|3283| tRNAscan exon 97020 97058 . + . transcript_id "Parent=tRNA-Tyr6.r01";
gi|4283| rRNAscan exon 197020 197058 . - . transcript_id "Parent=rRNA-Tyr1.r01";
gi|5283| mRNAscan exon 295020 298059 . + . transcript_id "Parent=mRNA-Tyr2.r01";

파일은 탭으로 구분됩니다.

파일 2:

"Parent=tRNA-Tyr6.r01"; 12
"Parent=mRNA-Tyr2.r01"; 0

파일은 탭으로 구분됩니다.

원하는 출력:

"Parent=tRNA-Tyr6.r01"; 12 -
"Parent=mRNA-Tyr2.r01"; 0 +

"Parent=tRNA-Tyr6.r01";파일 1( )의 $10 열과 파일 2( )의 $1 열을 기준으로 이 두 파일을 병합하고 "Parent=tRNA-Tyr6.r01";파일 1( -/ +) 의 $7 열을 추가 하고 싶습니다.

내 해결책은 다음과 같습니다.

awk 'FNR==NR{a[$10]=$7;next} ($1 in a) {print $1,"2,a[$1]}' file2 file1 > Output

누구든지 나를 도와줄 수 있나요?

답변1

이것join유틸리티는 공통 열을 기반으로 두 파일의 행을 병합합니다. 해당 열을 기준으로 파일을 정렬해야 합니다.

join -t $'\t' -1 10 -2 1 -o 2.1,2.2,1.7 <(sort -t $'\t' -k10 file1) <(sort -t $'\t' file2)
  • $'\t'-t $'\t'필드 구분 기호로 사용됨을 나타내는 탭 문자입니다 .
  • join -1 10 -2 1첫 번째 파일의 필드 10이 두 번째 파일의 필드 1과 일치할 때 행 연결을 나타냅니다.
  • -o …출력할 필드를 나열합니다.
  • <(sort …)명령의 출력을 sort입력 중 하나로 사용합니다 join.

$'…'그리고 <(…)순수 sh에서는 작동하지 않는 ksh 또는 bash가 필요합니다.

이미 정렬되어 있으면 file2이것을 사용할 수 있으며 일반 sh에서 작동합니다.

sort -t $'\t' -k10 file1 |
join -t "$(printf \\t)" -1 10 -2 1 -o 2.1,2.2,1.7 - file2

파일 중 하나의 순서를 유지하려는 경우에도 를 사용할 수 있지만 join줄 번호를 먼저 추가하고 원래 줄 번호를 마지막으로 정렬합니다. 예를 들어 다음 순서를 유지하려면 다음을 수행합니다 file2.

join -t $'\t' -1 10 -2 1 -o 2.1,2.2,2.3,1.7 \
     <(sort -t $'\t' -k10 file1) \
     <(<file2 nl | sort -t $'\t' -k 2,2) |
sort | cut -d $'\t' -f 2-

관련 정보