다음과 같은 fasta 파일이 있습니다.
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]
AGCAATTCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACATCGTGCAAGACAAACAACAAGTGCGTTACGTCACGTTACGTTAATTCGTTCGTTCGTCTCTCTATTGCGTTGCGTTACGCTCTCGCCGCGGACCCAGCACCGCATACCCGCCCATACAAGTCATACAGTACACAACACAAAAACACAACCAACTATTTCCTTGGAAGAGAAAGCAAGCCCAAAAC
>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]
TGAAAATATTAATTCTCAACCTTTTATGCGTTGGAGAGAAAGATATTTATTTTCAATAGAGGGAGTTAATCGTGCAGCGGCAGCAAGTGGTGAAATTAAAGGACATTATTTAAATGTTACTGCAGGTACAATGGAAGACATGTACGAACGCGCCAAGATTGATGTGCCTGAGAACCACATGAATAACGAGGAGCAATACACACTTCACTACCAAGAGTACCTTGTGGGTAGCTCGGCTGGTGTGCCCAAGGATATGAAGG
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]
GTTCTCTTCGGTGGCAGCCTTACGGCCGACCACCTGGTATTGTCGCATAATTCCCGCAGCAGTCATGATGTCTATTGTTTGTCGTGAAAAGAAATGAATTAAGAGAGTCATAGTTACTCCCGCCGTTTACCCGCGCTTGGTTGAATTCCTTCACTTTGACATTCAGAGCACTGGGCAGAAATCACATTGCGTCAACACCATCTCTGTTTCAACGAAATCAGCAGTATCTGTAGAAGTGTAGTTAAAACTAATATCTTTCC
첫 번째 fasta의 순서를 변경하지 않고 제목의 시작 부분을 사용하여 다른 fasta 파일에 포함된 제목에 종 이름을 추가하고 싶습니다.
>TRINITY_DN100_c0_g1_i1 HQ912515@Guinardia_delicatula
AGCAATCCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACACCGTGC
>TRINITY_DN105_c0_g1_i1 KR048205@Mougeotia_transeaui
AGCAATTCAAAGTGCTGCAATCTGGGCTCGTGAAAACGATATGTTATTACACTTACACCGTGCA
>TRINITY_DN103_c0_g1_i1 RP957897@Luticola_sparsipunctata
AGCAATTCAAAGTGCTGCAATCTGGGCTCGTGAAAACGATATGATTTTACACTTACACCGTGCA
나는 다음과 같은 것을 원합니다 :
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]@Guinardia_delicatula
AGCAATTCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACATCGTGCAAGACAAACAACAAGTGCGTTACGTCACGTTACGTTAATTCGTTCGTTCGTCTCTCTATTGCGTTGCGTTACGCTCTCGCCGCGGACCCAGCACCGCATACCCGCCCATACAAGTCATACAGTACACAACACAAAAACACAACCAACTATTTCCTTGGAAGAGAAAGCAAGCCCAAAAC
>TRINITY_DN100_c0_g1_i1 len=260 path=[0:0-259]@Mougeotia_transeaui
TGAAAATATTAATTCTCAACCTTTTATGCGTTGGAGAGAAAGATATTTATTTTCAATAGAGGGAGTTAATCGTGCAGCGGCAGCAAGTGGTGAAATTAAAGGACATTATTTAAATGTTACTGCAGGTACAATGGAAGACATGTACGAACGCGCCAAGATTGATGTGCCTGAGAACCACATGAATAACGAGGAGCAATACACACTTCACTACCAAGAGTACCTTGTGGGTAGCTCGGCTGGTGTGCCCAAGGATATGAAGG
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]@Luticola_sparsipunctata
GTTCTCTTCGGTGGCAGCCTTACGGCCGACCACCTGGTATTGTCGCATAATTCCCGCAGCAGTCATGATGTCTATTGTTTGTCGTGAAAAGAAATGAATTAAGAGAGTCATAGTTACTCCCGCCGTTTACCCGCGCTTGGTTGAATTCCTTCACTTTGACATTCAGAGCACTGGGCAGAAATCACATTGCGTCAACACCATCTCTGTTTCAACGAAATCAGCAGTATCTGTAGAAGTGTAGTTAAAACTAATATCTTTCC
내가 무엇을 해야 하는지 아시나요?
답변1
설명하는 내용을 달성하는 한 가지 방법은 다음과 같습니다.
- 헤더가 있는 두 번째 파일을 사용하여 매핑 만들기
- 첫 번째 파일을 읽고 일치하는 줄을 지도의 일치 항목으로 바꿉니다.
예를 들어 awk를 사용하십시오.
awk -F@ 'NR == FNR { if ($0 ~ /^>/) { a[$1] = $0 }; next } { if ($0 ~ /^>/ && $0 in a) $0 = a[$0]; print }' second_file_with_headers first_file
예:
$ cat second_file_with_headers
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]@Guinardia_delicatula
AGCAATCCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACACCGTGC
>TRINITY_DN100_c0_g1_i1 KR048205>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]AGCAATTCAAAGTGCTGCAATCTGGGCTCGTGAAAACGATATGTTATTACACTTACACCGTGCA
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]@Luticola_sparsipunctata
AGCAATTCAAAGTGCTGCAATCTGGGCTCGTGAAAACGATATGATTTTACACTTACACCGTGCA
$ cat first_file
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]
AGCAATTCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACATCGTGCAAGACAAACAACAAGTGCGTTACGTCACGTTACGTTAATTCGTTCGTTCGTCTCTCTATTGCGTTGCGTTACGCTCTCGCCGCGGACCCAGCACCGCATACCCGCCCATACAAGTCATACAGTACACAACACAAAAACACAACCAACTATTTCCTTGGAAGAGAAAGCAAGCCCAAAAC
>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]
TGAAAATATTAATTCTCAACCTTTTATGCGTTGGAGAGAAAGATATTTATTTTCAATAGAGGGAGTTAATCGTGCAGCGGCAGCAAGTGGTGAAATTAAAGGACATTATTTAAATGTTACTGCAGGTACAATGGAAGACATGTACGAACGCGCCAAGATTGATGTGCCTGAGAACCACATGAATAACGAGGAGCAATACACACTTCACTACCAAGAGTACCTTGTGGGTAGCTCGGCTGGTGTGCCCAAGGATATGAAGG
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]
GTTCTCTTCGGTGGCAGCCTTACGGCCGACCACCTGGTATTGTCGCATAATTCCCGCAGCAGTCATGATGTCTATTGTTTGTCGTGAAAAGAAATGAATTAAGAGAGTCATAGTTACTCCCGCCGTTTACCCGCGCTTGGTTGAATTCCTTCACTTTGACATTCAGAGCACTGGGCAGAAATCACATTGCGTCAACACCATCTCTGTTTCAACGAAATCAGCAGTATCTGTAGAAGTGTAGTTAAAACTAATATCTTTCC
$ awk -F@ 'NR == FNR { if ($0 ~ /^>/) { a[$1] = $0 }; next } { if ($0 ~ /^>/ && $0 in a) $0 = a[$0]; print }' second_file_with_headers first_file
>TRINITY_DN100_c0_g1_i1 len=242 path=[0:0-241]@Guinardia_delicatula
AGCAATTCAAACTGCTGCAATCTGGGCTCGTGAAAACGATATGGTATTACACTTACATCGTGCAAGACAAACAACAAGTGCGTTACGTCACGTTACGTTAATTCGTTCGTTCGTCTCTCTATTGCGTTGCGTTACGCTCTCGCCGCGGACCCAGCACCGCATACCCGCCCATACAAGTCATACAGTACACAACACAAAAACACAACCAACTATTTCCTTGGAAGAGAAAGCAAGCCCAAAAC
>TRINITY_DN105_c0_g1_i1 len=260 path=[0:0-259]
TGAAAATATTAATTCTCAACCTTTTATGCGTTGGAGAGAAAGATATTTATTTTCAATAGAGGGAGTTAATCGTGCAGCGGCAGCAAGTGGTGAAATTAAAGGACATTATTTAAATGTTACTGCAGGTACAATGGAAGACATGTACGAACGCGCCAAGATTGATGTGCCTGAGAACCACATGAATAACGAGGAGCAATACACACTTCACTACCAAGAGTACCTTGTGGGTAGCTCGGCTGGTGTGCCCAAGGATATGAAGG
>TRINITY_DN103_c0_g1_i1 len=260 path=[0:0-259]@Luticola_sparsipunctata
GTTCTCTTCGGTGGCAGCCTTACGGCCGACCACCTGGTATTGTCGCATAATTCCCGCAGCAGTCATGATGTCTATTGTTTGTCGTGAAAAGAAATGAATTAAGAGAGTCATAGTTACTCCCGCCGTTTACCCGCGCTTGGTTGAATTCCTTCACTTTGACATTCAGAGCACTGGGCAGAAATCACATTGCGTCAACACCATCTCTGTTTCAACGAAATCAGCAGTATCTGTAGAAGTGTAGTTAAAACTAATATCTTTCC
$
awk 스크립트는 쉽게 설명될 수 있습니다:
awk # the awk program, can be gawk, mawk or any other implementation
-F@ # Sets FS="@" . This tells awk to split on the @ character.
NR == FNR { if ($0 ~ /^>/) { a[$1] = $0 }; next }
# While handling the first argument (here, second_file_with_headers)
# For lines starting with >, store the line into an array with the part before @ as the key
# Discard all lines in this file with 'next'
{ if ($0 ~ /^>/ && $0 in a) $0 = a[$0]; print }
# For all other lines, meaning that we are now working on the second argument (first_file)
# For lines starting with >, change the line into the stored version from the array if it exists
# then print the line
second_file_with_headers
# Use the file with the headers as the first argument
first_file
# Use the file which needs to be updated as the second argument
답변2
awk -F'[@[:blank:]]+' '
NR==FNR { if(/^>/) seen[$1]=$NF; next }
{ if($1 in seen) $0=$0 "@" seen[$1]; print }' second.fasta first.fasta
우리는 -F
지정할 수 있습니다에프@
필드 구분 기호를 문자와 [:blank:]
한 번 이상 나타날 수 있는 공백(탭/공백) 으로 설정합니다 [...]+
. 따라서 필드는 이러한 문자로 구분됩니다.
NF==FNR
항상 참인 조건이다앗이는 첫 번째 입력 파일(Second.fasta파일은 여기에 있음); 각 입력 줄마다 증가하지만 NR
다음 입력 파일에서는 다시 1로 재설정됩니다.FNR
FNR
이는 if(/^>/)
행이 문자( ^
정규식에서 행의 시작을 가리키는 문자) 로 시작하는지 확인하고 >
, 그렇다면 마지막 필드를 $NF
연관된 배열(이름은 )에 저장하고 seen
#1을$1
아카이브로 저장하는 조건입니다. 열쇠.
이 next
문은 나머지 코드 처리를 건너뛰고 코드의 시작 부분으로 다시 점프합니다. NR==FNR
조건이 여전히 true이면 다음 코드를 반복하고 NR==FNR { ... }
, 그렇지 않으면 다음 블록이 실행되고 두 번째 입력 파일에서 실행됩니다.첫 번째.fasta배열에서 첫 번째 필드를 찾을 수 있는지 확인하고 seen
, 그렇다면 발견된 키의 값을 행 끝에 추가한 다음 print
전체 행에서 $0
(업데이트 여부에 관계없이) 모든 작업을 수행합니다.
또는 두 파일의 모든 헤더가 표시되고 동일한 줄 번호에 있는 경우 버퍼링 대신 다음을 수행할 수 있습니다.Second.fasta파일을 메모리에 저장합니다.
paste -d@ first.fasta second.fasta |awk -F@ '/^>/{ $1=$1 $NF } { print $1 }'