
수천 개의 항목이 포함된 대규모 Genbank 파일에서 항목을 추출하려고 합니다. 검색 문자열에는 고유한 유전자 이름을 사용했는데 매우 효과적이었습니다. 까다로운 부분은 특정 유전자에 대한 전체 항목을 인쇄하고 싶다는 것입니다. 항목은 LOCUS라는 단어로 시작하고 //로 끝나고 그 사이 어딘가에 유전자 이름이 포함되어 있습니다. grep의 플래그 -A
, -B
및 를 사용하여 -C
인쇄 할 수 있다는 것을 알고 있습니다.N문자열은 앞/뒤 줄과 일치하지만 실제 항목의 길이는 가변적입니다. grep을 사용하여 문자열(유전자 이름)을 검색한 다음 일치하는 항목 앞의 모든 줄("LOCUS"로 시작하는 줄 포함)과 모든 줄(항목 끝을 나타내는 줄 포함)을 인쇄하려면 어떻게 해야 합니까? "//" ?
저는 모든 제안에 열려 있습니다. 문자열("LOCUS" 및 "//") 또는 이와 유사한 항목과 일치하도록 -A
및 플래그를 얻을 수 있는 방법이 있습니까 ? -B
대신 awk를 사용해야 하나요?
편집: 다음은 간단한 입력 예입니다. 각 레코드는 "LOCUS"로 시작하고 "//"로 끝납니다. 이 예에는 세 가지 레코드가 포함되어 있습니다.
LOCUS scaffold1|size100
/gene="gene1"
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//
LOCUS scaffold99|size
/gene="gene2"
CGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//
LOCUS scaffold199|size1000
/gene="gene3"
AGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
AGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
AGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//
"gene2"를 검색하고 일치 전의 첫 번째 "LOCUS" 인스턴스부터 일치 후의 첫 번째 "//" 인스턴스까지 텍스트를 인쇄하고 싶습니다. 이상적으로는 다음과 같은 출력을 원합니다.
LOCUS scaffold99|size
/gene="gene2"
CGTTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
GATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACAGATTACA
//
답변1
다음과 같은 상황에서는 매우 쉽습니다 awk
.
awk -vtarget=fox '
/LOCUS/ { in_gene = 1 }
in_gene { if (gene == "") gene = $0; else gene = gene ORS $0; }
$0 ~ target { found = 1 }
/\/\// { if (in_gene && found) print gene
gene = ""; in_gene = 0; found = 0
}
'
- 변수를
target
검색하려는 문자열(유전자 이름)로 설정합니다. 나는 이것을fox
예로 사용하고 있습니다. - 이 단어를 보면
LOCUS
우리는 유전자를 찾고 있다는 것을 알 수 있습니다. - 우리가 유전자에 초점을 맞추는 한 그 내용은 축적됩니다. 첫 번째 줄( 행)이 방금 변수
LOCUS
에 할당되었습니다 .gene
그런 다음 이전 값과 추가된 값 사이에 새 줄(ORS = 출력 레코드 구분 기호)을 사용하여 현재 줄( )을 변수$0
에 추가(추가)합니다.gene
- 현재 유전자에 찾고 있는 유전자 이름이 포함되어 있으면 플래그를 설정합니다
found
. - 우리는 유전자를 발견하면 현재의 유전자가 우리가 찾고 있는 유전자인지 확인하고, 그렇다면 그것을 인쇄하는
/\/\//
다소 추악한 방법을 사용해야 합니다 .//
그런 다음 재설정하여 검색을 계속하세요. 찾고 있는 유전자가 파일에서 한 번만 발생한다고 확신하는 경우(또는 첫 번째 발생만 원하는 경우) 여기에서 종료할 수 있습니다.
답변2
때마다유전자레코드가 사이에 있다고 지정 LOCUS...//
하면 다음을 수행할 수 있습니다.
gawk '/gene2/{printf $0 RS}' RS='\n//\n' infile
우리는 정의했다RS\n
각 레코드는 " ewline //\n
ewline"(포함된 행만 ) 과 같은 고유한 값으로 끝나고 //
, printf와 일치하는 각 레코드에 대해 /gene2/
로그를 기록 $0
하고 다시 복원합니다 RS
.
노트:
선행/후행 공백(공백/탭)이 포함되는 경우를 관리하려면 RS
로 변경할 수 있지만 RS='\n( |\t)*//( |\t)*\n'
다음을 사용해야 합니다.RT
?(암소 비슷한 일종의 영양awk 확장명) 유지RS그대로 또는 직접 printf "//"
.
gawk '/gene2/{printf $0 RT}' RS='\n( |\t)*//( |\t)*\n' infile
~에서man gawk
:
RS 기본값은 줄 바꿈인 레코드 구분 기호를 입력합니다.
RT 레코드 터미네이터. 다이다이지RT지정된 문자 또는 정규식과 일치하는 텍스트를 입력하려면RS.
? : 녹화 종료 확인 후,멍하니변수 설정RT입력의 텍스트와 일치시키려면RS. 언제RS단일 문자이고,RT동일한 단일 문자를 포함합니다. 그러나 언제 RS는정규식,RT정규식과 일치하는 실제 입력 텍스트를 포함합니다.
답변3
sed -ne '
/^LOCUS/,\|^//|!d
H;/^LOCUS/h
\|^/gene="gene2"|{
s/.*//;x;H
}
\|^//|!d;g
s/^\n//p
' input_file
피복재:
,
¶여기서 범위 연산자를 사용할 수 있습니다
¶ 먼저 올바른 범위, 즉 //
궤적의 시작 및 끝 범위를 선택하십시오.
¶ 예약된 공간에 라인을 저장하십시오.
¶ gene2의 골든 라인에 도달하면 언제 인쇄할지 말지 알려주는 플래그로 시작 부분에 개행 문자를 넣습니다.
¶ //
line은 예약된 영역 앞에 개행 문자가 있는지 여부에 따라 인쇄 활동을 트리거합니다.