문자열의 특정 시작부터 끝까지 일치 전후의 텍스트를 인쇄합니다.

문자열의 특정 시작부터 끝까지 일치 전후의 텍스트를 인쇄합니다.

수천 개의 항목이 포함된 대규모 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 //\newline"(포함된 행만 ) 과 같은 고유한 값으로 끝나고 //, 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은 예약된 영역 앞에 개행 문자가 있는지 여부에 따라 인쇄 활동을 트리거합니다.

관련 정보