저는 50,000개 이상의 유전자 ID 행과 그 서열을 포함하는 다음과 같은 파일을 작업 중입니다.
gene_A:3342234 CTCTTTCTTTTACGCCT
gene_A:1244-5205 CTCTTTCTTTTACGCCT
gene_A:1838438 CTCTTTCTTTTACGCCT
gene_B:1848584 CTCTTTCTTTTACGCCT
gene_B:1029-4920 CTCTTTCTTTTACGCCT
gene_C:3849029 CTCTTTCTTTTACGCCT
이들 모두에는 유전자 ID가 있고 그 뒤에 콜론, 7-9자리 참조 번호 및 (일부는 대시 포함)이 옵니다.
geneA
유전자 ID를 및 등의 실제 이름으로 바꾸고 geneB
그 뒤에 있는 정보를 유지 하고 싶습니다 . 원하는 출력:
geneA CTCTTTCTTTTACGCCT
geneA CTCTTTCTTTTACGCCT
geneA CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
sed를 처음 사용하는 것이므로 어디서부터 시작해야 할지 잘 모르겠습니다. gene_A가 포함된 모든 행을 바꾸는 방법을 알고 있지만 's/gene_A.*/geneA/'
유전자 ID 뒤에 있는 정보를 보존하는 방법을 잘 모르겠습니다.
답변1
나는 귀하의 예가 좋지 않다고 생각하며 실제로 다음과 같은 파일을 사용하여 프로그래밍 방식으로 변환하는 대신 유전자 ID를 유전자 이름에 매핑해야 합니다.
$ cat ids2names
gene_A when
gene_B chapmen
gene_C billies
그렇다면 awk를 사용하여 다음을 수행할 수 있습니다.
$ awk -F'[: ]' 'NR==FNR{map[$1]=$2; next} {print map[$1], $3}' ids2names file
when CTCTTTCTTTTACGCCT
when CTCTTTCTTTTACGCCT
when CTCTTTCTTTTACGCCT
chapmen CTCTTTCTTTTACGCCT
chapmen CTCTTTCTTTTACGCCT
billies CTCTTTCTTTTACGCCT
그렇지 않고 유전자 이름이 실제로 _
제거된 예에서와 같이 유전자 ID일 경우...
아무 sed나 사용하세요:
$ sed 's/_\([^:]*\)[^ ]*/\1/' file
geneA CTCTTTCTTTTACGCCT
geneA CTCTTTCTTTTACGCCT
geneA CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
geneC CTCTTTCTTTTACGCCT
아니면 어떤 이상한 :
$ awk -F'[_: ]' '{print $1 $2, $4}' file
geneA CTCTTTCTTTTACGCCT
geneA CTCTTTCTTTTACGCCT
geneA CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
geneB CTCTTTCTTTTACGCCT
geneC CTCTTTCTTTTACGCCT
입력의 공백이 항상 단일 공백이 아닌 경우 -F'[: ]'
awk 스크립트의 OR -F'[:[:blank:]]+'
(있는 경우 그대로 두기) 및 sed 스크립트의 OR로 변경합니다.-F'[: \t]+'
_
[^ ]
[^[:blank:]]
[^ \t]
답변2
사용행복하다(이전 Perl_6)
~$ raku -pe 's/^ \w+ <( \: <[0..9-]>+ //;' file
#OR
~$ raku -pe 's/^ (\w+) \: <[0..9-]>+ /$0/;' file
위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 이 두 가지 답변은 Raku의 sed와 유사한 자동 인쇄 프로그레시브 플래그를 사용합니다 (Raku의 awk와 같은 비자동 인쇄 프로그레시브 플래그를 -pe
사용하는 다른 답변을 상상할 수 있습니다 ).-ne
즉, ^
문자열의 시작(줄), \w+
하나 이상의 숫자 또는 밑줄, 콜론 , 아라비아 숫자와 하이픈 으로 구성된 사용자 정의 문자 클래스가 \:
뒤따르는 것을 감지합니다. (유니코드 숫자를 포함하려면 대신 사용하세요).<[0..9-]>+
-
<+ :N + [-]>+
입력 예:
gene_A:3342234 CTCTTTCTTTTACGCCT
gene_A:1244-5205 CTCTTTCTTTTACGCCT
gene_A:1838438 CTCTTTCTTTTACGCCT
gene_B:1848584 CTCTTTCTTTTACGCCT
gene_B:1029-4920 CTCTTTCTTTTACGCCT
gene_C:3849029 CTCTTTCTTTTACGCCT
샘플 출력(두 가지 코드 예):
gene_A CTCTTTCTTTTACGCCT
gene_A CTCTTTCTTTTACGCCT
gene_A CTCTTTCTTTTACGCCT
gene_B CTCTTTCTTTTACGCCT
gene_B CTCTTTCTTTTACGCCT
gene_C CTCTTTCTTTTACGCCT
각 답변에 대한 설명:
Raku의
<(
캡처 플래그는 콜론 이전의 일치 항목을 제거하는 데 사용됩니다(캡처 플래그는 단독으로 작동하지만 함께 사용할 수 있음<(
및/또는).)>
나머지 캡처는 대체된 절반에서 "대체되지 않음", 즉 삭제됩니다.Raku의
(
...)
숫자 캡처 괄호는 유전자 이름을 캡처하는 데 사용되며 본질적으로 나중에 일치하는 항목을 삭제합니다. 그런 다음 현재 캐치는$0
교체 하프에 배치됩니다. 즉, 경기의 나머지 부분이 제거됩니다.
참고: 정말로 "잡아서 수정"(예: 유전자 이름에서 밑줄 제거)이 필요한 경우 Raku를 사용하면 대체된 절반에서 코드를 실행할 수 있습니다. 다음은 trans
모든 밑줄을 빈 문자열(즉, 아무것도 없음)로 변환하고 밑줄이 제거된 유전자 이름을 반환합니다.
~$ raku -pe 's/^ (\w+) \: <[0..9-]>+ /{$0.trans("_" => "")}/;' file
#OR (more simply)
~$ raku -pe 's/^ (\w+) \: <[0..9-]>+ /$0.trans("_" => "")/;' file
답변3
sed -E 's/(gene_[A-Z]):[0-9-]+/\1/' input.txt
이 명령은 -E
옵션을 사용하여 확장 정규식을 활성화하고 그룹의 유전자 ID를 캡처한 (gene_[A-Z])
다음 콜론과 일련의 숫자 및 대시를 사용합니다 :[0-9-]+
. 대체 항목은 \1
원본 입력 파일의 유전자 ID를 참조하며, 이 파일에는 유전자 ID 목록과 해당 시퀀스가 포함되어 있습니다(이 예에서는 input.txt라는 이름).
답변4
이 작업은 두 단계로 진행하겠습니다 sed
.
가정 gene.txt
:
gene_A:3342234 CTCTTTCTTTTACGCCT
gene_A:1244-5205 CTCTTTCTTTTACGCCT
gene_A:1838438 CTCTTTCTTTTACGCCT
gene_B:1848584 CTCTTTCTTTTACGCCT
gene_B:1029-4920 CTCTTTCTTTTACGCCT
gene_C:3849029 CTCTTTCTTTTACGCCT
중간 필드를 제거합니다(
:
a ~ a 로 구분).
> sed 's/:.* / /' gene.txt gene_A CTCTTTCTTTTACGCCT gene_A CTCTTTCTTTTACGCCT gene_A CTCTTTCTTTTACGCCT gene_B CTCTTTCTTTTACGCCT gene_B CTCTTTCTTTTACGCCT gene_C CTCTTTCTTTTACGCCT
이 명령은 콜론부터 공백까지 일치시킨 다음 모든 것을 공백으로 바꿉니다.
밑줄을 제거합니다(첫 번째 명령에 추가됨).
> sed 's/:.* / /;s/_//' gene.txt geneA CTCTTTCTTTTACGCCT geneA CTCTTTCTTTTACGCCT geneA CTCTTTCTTTTACGCCT geneB CTCTTTCTTTTACGCCT geneB CTCTTTCTTTTACGCCT geneC CTCTTTCTTTTACGCCT
이 명령은 세미콜론을 사용하여 두 개의 독립적인 대체 시도를 구분하지만 첫 번째 대체가 발생하면 첫 번째 대체의 결과에 대해 두 번째 대체가 계속 발생합니다. 이 솔루션의 "문구"는 첫 번째 밑줄만 제거합니다(
g
대체 끝에는 없음).