(수정됨) 질문이 많은 파일이 있습니다. 예를 들어:
Chr1_RagTag_p AUGUSTUS transcript 393571 396143 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; gene_name "AT1G02100"; oId "g109.t1"; cmp_ref "AT1G02100.1"; class_code "="; tss_id "TSS64"; num_samples "1";
Chr1_RagTag_p AUGUSTUS exon 393571 393638 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "1";
Chr1_RagTag_p AUGUSTUS exon 393732 393945 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "2";
Chr1_RagTag_p AUGUSTUS exon 394047 394094 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "3";
Chr1_RagTag_p AUGUSTUS exon 394178 394259 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "4";
Chr1_RagTag_p AUGUSTUS exon 394457 394559 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "5";
Chr1_RagTag_p AUGUSTUS exon 394698 394818 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "6";
Chr1_RagTag_p AUGUSTUS exon 394911 394958 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "7";
Chr1_RagTag_p AUGUSTUS exon 395153 395236 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "8";
Chr1_RagTag_p AUGUSTUS exon 395347 395411 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "9";
Chr1_RagTag_p AUGUSTUS exon 395716 395767 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "10";
Chr1_RagTag_p AUGUSTUS exon 395957 395995 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "11";
Chr1_RagTag_p AUGUSTUS exon 396069 396143 . + . transcript_id "TCONS_00000070"; gene_id "XLOC_000060"; exon_number "12";
Chr1_RagTag_p manual transcript 396451 399224 . + . transcript_id "TCONS_00000071"; gene_id "XLOC_000060"; gene_name "AT1G02110"; oId "g110.t1"; cmp_ref "AT1G02110.1"; class_code "="; tss_id "TSS65"; num_samples "2";
Chr1_RagTag_p manual exon 396451 397570 . + . transcript_id "TCONS_00000071"; gene_id "XLOC_000060"; exon_number "1";
Chr1_RagTag_p manual exon 397661 397848 . + . transcript_id "TCONS_00000071"; gene_id "XLOC_000060"; exon_number "2";
Chr1_RagTag_p manual exon 397923 398146 . + . transcript_id "TCONS_00000071"; gene_id "XLOC_000060"; exon_number "3";
Chr1_RagTag_p manual exon 398367 399224 . + . transcript_id "TCONS_00000071"; gene_id "XLOC_000060"; exon_number "4";
Chr1_RagTag_p AUGUSTUS transcript 77905 78201 . + . transcript_id "TCONS_00000004"; gene_id "XLOC_000004"; oId "g15.t1"; cmp_ref "AT1G01150.1"; class_code "x"; cmp_ref_gene "AT1G01150"; tss_id "TSS4"; num_samples "1";
Chr1_RagTag_p AUGUSTUS exon 77905 78201 . + . transcript_id "TCONS_00000004"; gene_id "XLOC_000004"; exon_number "1";
에 따르면, 예에서는 두 개의 유전자가 있음을 분명히 알 수 있지만 gene_name
소프트웨어는 어떻게든 두 유전자를 하나의 유전자( gene_id
)로 병합합니다. for 행을 one 으로 gene_name
대체하여 gene_id
이러한 문제를 해결하고 싶습니다 transcript_name
. 그리고 세 번째 유전자( )에 대해서는 뒤에 부분이 없는 것으로 gene_id "XLOC_000004"
이름을 바꾸고 싶습니다.oId
.t[0-9]
출력은 다음과 같습니다
Chr1_RagTag_p AUGUSTUS transcript 393571 396143 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; gene_name "AT1G02100"; oId "g109.t1"; cmp_ref "AT1G02100.1"; class_code "="; tss_id "TSS64"; num_samples "1";
Chr1_RagTag_p AUGUSTUS exon 393571 393638 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "1";
Chr1_RagTag_p AUGUSTUS exon 393732 393945 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "2";
Chr1_RagTag_p AUGUSTUS exon 394047 394094 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "3";
Chr1_RagTag_p AUGUSTUS exon 394178 394259 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "4";
Chr1_RagTag_p AUGUSTUS exon 394457 394559 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "5";
Chr1_RagTag_p AUGUSTUS exon 394698 394818 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "6";
Chr1_RagTag_p AUGUSTUS exon 394911 394958 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "7";
Chr1_RagTag_p AUGUSTUS exon 395153 395236 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "8";
Chr1_RagTag_p AUGUSTUS exon 395347 395411 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "9";
Chr1_RagTag_p AUGUSTUS exon 395716 395767 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "10";
Chr1_RagTag_p AUGUSTUS exon 395957 395995 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "11";
Chr1_RagTag_p AUGUSTUS exon 396069 396143 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "12";
Chr1_RagTag_p manual transcript 396451 399224 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; gene_name "AT1G02110"; oId "g110.t1"; cmp_ref "AT1G02110.1"; class_code "="; tss_id "TSS65"; num_samples "2";
Chr1_RagTag_p manual exon 396451 397570 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "1";
Chr1_RagTag_p manual exon 397661 397848 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "2";
Chr1_RagTag_p manual exon 397923 398146 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "3";
Chr1_RagTag_p manual exon 398367 399224 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "4";
Chr1_RagTag_p AUGUSTUS transcript 77905 78201 . + . transcript_id "TCONS_00000004"; gene_id "g15"; oId "g15.t1"; cmp_ref "AT1G01150.1"; class_code "x"; cmp_ref_gene "AT1G01150"; tss_id "TSS4"; num_samples "1";
Chr1_RagTag_p AUGUSTUS exon 77905 78201 . + . transcript_id "TCONS_00000004"; gene_id "g15"; exon_number "1";
논리는 gene_name
by 를 grep transcript_id
한 다음 gene_id
숫자를 기준으로 각 줄의 the를 바꾸는 것 같습니다.gene_name
transcript_id
transcript_id
지금까지 나는 목록 을 만들었고gene_name
TCONS_00000070 AT1G02100
TCONS_00000071 AT1G02110
TCONS_00000004 g15
gene_id
그런 다음 관련 콘텐츠를 기반으로 각 행을 교체해야 합니다 . 하지만 어떻게 해야할지 모르겠습니다. 사용할 수 있나요?gene_name
transcript_id
sed
마지막으로 중요한 것은 내 실제 파일이 35000개의 서로 다른 trnascript_id
.
미리 감사드립니다!
답변1
이것이 모든 극단적인 경우를 다룰지는 알 수 없지만 귀하의 예에서는 귀하가 요구하는 작업을 수행합니다.
sed '/.*gene_name/{h;s///;s/;.*//;x;};G;s/gene_id[^;]*\(.*\)\n\(.*\)/gene_id\2\1/' file
gene_name
콘텐츠가 있는 경우 추출하여 예약된 공간에 저장하고 새로운 콘텐츠가 나타날 gene_id
때까지 모든 후속 콘텐츠의 대체 콘텐츠 로 사용합니다.gene_name
자세한 세부 사항:
/.*gene_name/
는주소, 내부의 모든 내용은{}
해당 패턴이 있는 줄에만 적용됩니다.- 모든 것을 엉망으로 만들기 전에 원래 행을
h
이전 공간 에 저장합니다. s///
이전 패턴(최대gene_name
)을 삭제하고s/;.*//
세미콜론으로 시작하는 모든 항목을 삭제합니다. 따라서 남은 것은 공백과 큰따옴표로 묶인 문자열뿐입니다.x
두 공간을 교환하면 이제 예약된 공간에 대체 공간이 있고 패턴 공간에 원래 라인이 있습니다.- 이제부터 모든 내용은 모든 줄에 적용됩니다.
G
예약된 공백이 각 줄에 추가되므로 줄, 개행 문자 및 대체 문자가 있습니다. s/gene_id[^;]*\(.*\)\n\(.*\)/gene_id\2\1/' is easier to write than to read:
[^;]matches everything between
유전자 IDand the
(, thus the part to be replaced. The
.) 대체parts cover the text before and after the embedded newline, so we can refer to them as
\1 \2`에 있습니다.and
gene_name
<CR>
마지막 단계를 설명하기 위해 포함된 개행 문자로 with를 사용하여 예약된 공간을 추가한 후 버퍼가 어떻게 보이는지 살펴보세요 .
Chr1_RagTag_p ………; gene_id "XLOC_000060"; exon_number "1";<CR> "AT1G02100"
\______v_____/\________v_______/ \____v____/
gene_id [^;]* \(.*\) \n \(.*\)
-E
확장 정규식을 사용하면 읽기가 더 쉬울 수도 있습니다(옵션).
sed -E '/.*gene_name/{h;s///;s/;.*//;x;};G;s/(gene_id)[^;]*(.*)\n(.*)/\1\3\2/' file
gene_name
업데이트는 업데이트 질문의 사례 없음을 고려합니다.
oId
나는 단순히 추출물과 유사 gene_name
하지만 그 전에 추출물을 추가했습니다. 따라서 그 뒤에 하나가 있으면 gene_name
덮어쓰게 됩니다 oId
. 이번에는 더 나은 가독성을 위해 줄을 구분합니다.
sed '
/.*oId/{
h
s///
s/\..*/"/
x
}
/.*gene_name/{
h
s///
s/;.*//
x
}
G
s/gene_id[^;]*\(.*\)\n\(.*\)/gene_id\2\1/' file
답변2
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ awk '
match($0,/gene_name "[^"]+"/) {
name = substr($0,RSTART+10,RLENGTH-10)
}
match($0,/gene_id "[^"]+"/) {
$0 = substr($0,1,RSTART+7) name substr($0,RSTART+RLENGTH)
}
{ print }
' file
Chr1_RagTag_p AUGUSTUS transcript 393571 396143 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; gene_name "AT1G02100"; oId "g109.t1"; cmp_ref "AT1G02100.1"; class_code "="; tss_id "TSS64"; num_samples "1";
Chr1_RagTag_p AUGUSTUS exon 393571 393638 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "1";
Chr1_RagTag_p AUGUSTUS exon 393732 393945 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "2";
Chr1_RagTag_p AUGUSTUS exon 394047 394094 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "3";
Chr1_RagTag_p AUGUSTUS exon 394178 394259 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "4";
Chr1_RagTag_p AUGUSTUS exon 394457 394559 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "5";
Chr1_RagTag_p AUGUSTUS exon 394698 394818 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "6";
Chr1_RagTag_p AUGUSTUS exon 394911 394958 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "7";
Chr1_RagTag_p AUGUSTUS exon 395153 395236 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "8";
Chr1_RagTag_p AUGUSTUS exon 395347 395411 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "9";
Chr1_RagTag_p AUGUSTUS exon 395716 395767 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "10";
Chr1_RagTag_p AUGUSTUS exon 395957 395995 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "11";
Chr1_RagTag_p AUGUSTUS exon 396069 396143 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "12";
Chr1_RagTag_p manual transcript 396451 399224 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; gene_name "AT1G02110"; oId "g110.t1"; cmp_ref "AT1G02110.1"; class_code "="; tss_id "TSS65"; num_samples "2";
Chr1_RagTag_p manual exon 396451 397570 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "1";
Chr1_RagTag_p manual exon 397661 397848 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "2";
Chr1_RagTag_p manual exon 397923 398146 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "3";
Chr1_RagTag_p manual exon 398367 399224 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "4";
답변3
또는 다시 gawk
(GNU Awk)를 사용하여 이를 수행하는 더 간단한 방법은 다음과 같습니다.
$ awk '/gene_name/ {gene_id=$14; $12=$14; print; next;} {$12=gene_id; print;}' file
또는 @EdMorton이 제안한 것처럼 더 간단합니다.
$ awk '/gene_name/ {gene_id=$14} {$12=gene_id; print}' file
Chr1_RagTag_p AUGUSTUS transcript 393571 396143 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; gene_name "AT1G02100"; oId "g109.t1"; cmp_ref "AT1G02100.1"; class_code "="; tss_id "TSS64"; num_samples "1";
Chr1_RagTag_p AUGUSTUS exon 393571 393638 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "1";
Chr1_RagTag_p AUGUSTUS exon 393732 393945 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "2";
Chr1_RagTag_p AUGUSTUS exon 394047 394094 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "3";
Chr1_RagTag_p AUGUSTUS exon 394178 394259 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "4";
Chr1_RagTag_p AUGUSTUS exon 394457 394559 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "5";
Chr1_RagTag_p AUGUSTUS exon 394698 394818 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "6";
Chr1_RagTag_p AUGUSTUS exon 394911 394958 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "7";
Chr1_RagTag_p AUGUSTUS exon 395153 395236 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "8";
Chr1_RagTag_p AUGUSTUS exon 395347 395411 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "9";
Chr1_RagTag_p AUGUSTUS exon 395716 395767 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "10";
Chr1_RagTag_p AUGUSTUS exon 395957 395995 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "11";
Chr1_RagTag_p AUGUSTUS exon 396069 396143 . + . transcript_id "TCONS_00000070"; gene_id "AT1G02100"; exon_number "12";
Chr1_RagTag_p manual transcript 396451 399224 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; gene_name "AT1G02110"; oId "g110.t1"; cmp_ref "AT1G02110.1"; class_code "="; tss_id "TSS65"; num_samples "2";
Chr1_RagTag_p manual exon 396451 397570 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "1";
Chr1_RagTag_p manual exon 397661 397848 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "2";
Chr1_RagTag_p manual exon 397923 398146 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "3";
Chr1_RagTag_p manual exon 398367 399224 . + . transcript_id "TCONS_00000071"; gene_id "AT1G02110"; exon_number "4";
참고:
현재 형식에서는 현재 필드에 하나 이상의 공백이 포함될 가능성이 제외되지만 이 솔루션이 더 간단해질 것이라고 생각하지 않습니다. 이를 위해서는 @EdMorton의 솔루션이 필요합니다.
답변4
저를 위해 스크립트를 작성해주신 모든 분들께 정말 감사드립니다! 어젯밤에 고민하다가 다음과 같은 방법을 생각해냈습니다.
위의 정보가 포함된 입력 파일의 이름을 Sample.gtf로 지정합니다.
나는 transcription_id, gene_id 및 gene_name을 포함하는 파일을 만들었습니다.
$ grep "oId" sample.gtf | awk '{print $10,$12,$14}' | sed 's/\"//g' | sed 's/\;//g' | sed '
s/\.[^\.]*$/ /g' > gene_id_replace_list.txt
# here I use `oId` because I found that some of the lines has no `gene_name`. In a case of no `gene_name`, I would like to grab `oId` as the a `gene_name` for replacement of `gene_id`.
$ head gene_id_replace_list.txt
TCONS_00000070 XLOC_000060 AT1G02100
TCONS_00000071 XLOC_000060 AT1G02110
sed
그런 다음 위에 게시한 Phillipos와 다소 유사한 명령을 사용하여 sed에 루프를 한 줄씩 작성했습니다 .
while IFS= read -r line; do
TransId=$(echo $line | awk '{print $1}')
GeneId=$(echo $line | awk '{print $2}')
TairId=$(echo $line | awk '{print $3}')
sed -i "/${TransId}/ s/${GeneId}/${TairId}/g" sample.gtf
done < gene_id_replace_list.txt
그러나 내 전체 파일에는 35000개의 기록이 있고 지금까지 이 스크립트는 기록당 거의 1초 동안 실행되기 때문에 이 코드가 별로 마음에 들지 않습니다. 그렇다면 더 나은 제안이 있는 사람이 있나요?
위의 Philippos 명령을 적용하여 gene_name이 없는 경우를 처리하고 각 대체 항목의 transcription_id를 더 쉽게 인쇄하고 싶습니다(끝에 코드가 대체하는 것이 무엇인지 확인해야 합니다. 죄송합니다). Philippos가 제안한 것과 유사한 한 줄 명령이 sed
훨씬 더 빠를 수도 있습니까?