문자열에서 하위 문자열이 반복되는 횟수를 계산합니다.

문자열에서 하위 문자열이 반복되는 횟수를 계산합니다.

유전자 서열이 포함된 파일이 있습니다. 예를 들면 다음과 같습니다.

ATGTGGATGGTGGGTTACAATGAAGGTGGTGAGTTCAACATGGCTGATTATCCATTCAGTGGAAGGAAACTAAGGCCTCTCATTCCAAGACCAGTCCCAGTCCCTACTACTTCTCCTAACAGCACTTCAACTATAACTCCTTCCTTAAACCGCATTCATGGTGGCAATGATTTATTTTCACAATATCATCACAATCTGCAGCAGCAAGCATCAGTAGGAGATCATAGCAAGAGATCAGAGTTGAATAATAATAATAATCCATCTGCAGCAGTTGTGGTGAGTTCAAGATGGAATCCAACACCAGAACAGTTAAGAGCACTGGAAGAATTGTATAGAAGAGGAACAAGAACACCTTCTGCTGAGCAAATCCAACAAATAACTGCCCAGCTTAGAAAATTTGGAAAAATTGAAGGCAAAAATGTTTTCTATTGGTTTCAGAATCACAAAGCCAGAGAAAGGCAAAAACGACGGCGTCAAATGGAATCAGCAGCTGCTGAGTTTGATTCTGCTATTGAAAAGAAAGACTTAGGCGCAAGTAGG


ACAGTGTTTGAAGTTGAACACACTAAAAACTGGCTACCATCTACAAATTCCAGTACCAGTACTCTTCATCTTGCAGAGGAATCTGTTTCAATTCAAAGGTCAGCAGCAGCAAAAGCAGATGGATGGCTCCAATTCGATGAAGCAGAATTACAGCAAAGAAGAAACTTTATGGAAAGGAATGCCACGTGGCATATGATGCAGTTAACTTCTTCTTGTCCTACAGCTAGCATGTCCACCACAACCACAGTAACAACTAGACTTATGGACCCAAAACTCATCAAGACCCATGAACTCAACTTATTCATTTCACCTCACACATACAAAGAAAGAGAAAACGCTTTTATCCACTTAAATACTAGTAGTACTCATCAAAATGAATCTGATCAAACCCTTCAACTTTTCCCAATAAGGAATGGAGATCATGGATGCACTGATCATCATCATCATCATCATAACATTATCAAAGAGACACAGATATCAGCTTCAGCAATCAATGCACCCAACCAGTTTATTGAGTTTCTTCCCTTGAAAAACTGA

위 문자열에서 "ATG" 하위 문자열의 발생 횟수를 계산하려고 합니다(개행 없이 한 줄만). 내 파일에는 수십 개의 이러한 시퀀스가 ​​포함되어 있으며 각 시퀀스에 "ATG"가 몇 개 있는지 계산할 수 있기를 원합니다. 각 시퀀스는 빈 줄로 다른 시퀀스와 구분됩니다.

grep을 시도했지만 어떤 옵션을 사용해야 할지 모르겠고(grep이 트릭을 수행하는 경우) Google에서 awk 예제를 검색했지만 옵션을 찾지 못했습니다.

답변1

ATG각 행의 발생 횟수를 반환합니다.

awk -F'ATG' 'NF{print NF-1}' testfile

이는 하나 이상의 줄을 포함하는 파일에 적용됩니다.

실시예 1

다음 테스트 파일을 고려해보세요.

$ cat testfile
xxATGxxATG

ATGxxxATGxxx

xxATGxxxxATGxxATGxx

이 코드는 ATG 발생 횟수를 올바르게 계산합니다.

$ awk -F'ATG' 'NF{print NF-1}' testfile
2
2
3

실시예 2

현재 버전의 질문 예를 사용하면 다음과 같습니다.

$ cat >file1
ATGTGGATGGTGGGTTACAATGAAGGTGGTGAGTTCAACATGGCTGATTATCCATTCAGTGGAAGGAAACTAAGGCCTCTCATTCCAAGACCAGTCCCAGTCCCTACTACTTCTCCTAACAGCACTTCAACTATAACTCCTTCCTTAAACCGCATTCATGGTGGCAATGATTTATTTTCACAATATCATCACAATCTGCAGCAGCAAGCATCAGTAGGAGATCATAGCAAGAGATCAGAGTTGAATAATAATAATAATCCATCTGCAGCAGTTGTGGTGAGTTCAAGATGGAATCCAACACCAGAACAGTTAAGAGCACTGGAAGAATTGTATAGAAGAGGAACAAGAACACCTTCTGCTGAGCAAATCCAACAAATAACTGCCCAGCTTAGAAAATTTGGAAAAATTGAAGGCAAAAATGTTTTCTATTGGTTTCAGAATCACAAAGCCAGAGAAAGGCAAAAACGACGGCGTCAAATGGAATCAGCAGCTGCTGAGTTTGATTCTGCTATTGAAAAGAAAGACTTAGGCGCAAGTAGG


ACAGTGTTTGAAGTTGAACACACTAAAAACTGGCTACCATCTACAAATTCCAGTACCAGTACTCTTCATCTTGCAGAGGAATCTGTTTCAATTCAAAGGTCAGCAGCAGCAAAAGCAGATGGATGGCTCCAATTCGATGAAGCAGAATTACAGCAAAGAAGAAACTTTATGGAAAGGAATGCCACGTGGCATATGATGCAGTTAACTTCTTCTTGTCCTACAGCTAGCATGTCCACCACAACCACAGTAACAACTAGACTTATGGACCCAAAACTCATCAAGACCCATGAACTCAACTTATTCATTTCACCTCACACATACAAAGAAAGAGAAAACGCTTTTATCCACTTAAATACTAGTAGTACTCATCAAAATGAATCTGATCAAACCCTTCAACTTTTCCCAATAAGGAATGGAGATCATGGATGCACTGATCATCATCATCATCATCATAACATTATCAAAGAGACACAGATATCAGCTTCAGCAATCAATGCACCCAACCAGTTTATTGAGTTTCTTCCCTTGAAAAACTGA

그 결과는 다음과 같습니다.

$ awk -F'ATG' 'NF{print NF-1}' file1
9
15

어떻게 작동하나요?

awk는 파일의 각 줄을 암시적으로 반복합니다. 각 행은 필드로 구분됩니다.

  • -F'ATG'

    이는 awk에게 ATG필드 구분 기호로 사용하도록 지시합니다.

  • NF{print NF-1}

    이는 awk에게 비어 있지 않은 각 줄에 대해 필드 수에서 1을 뺀 값을 인쇄하도록 지시합니다.

    (빈 행에서 필드 수 NF는 0입니다. 따라서 이러한 행의 조건은 NFfalse로 평가되어 효과적으로 건너뜁니다.)

답변2

~에서man grep

-o, --only-matching
    Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.

그래서 당신은 시도해 볼 수 있습니다

$ grep -o 'ATG' file | wc -l

답변3

John1024의 테스트 파일을 사용하여 tachomi의 grep -o 아이디어를 개선합니다. 이는 수천 개의 라인을 생성하고 나중에 정확하게 추적해야 할 경우를 대비하여 개수를 포함하고 입력 파일의 어느 라인에 해당 개수가 있는지 표시하는 방법입니다. 카운트는 에서 왔습니다.

첫 번째는 John1024의 테스트 파일과 약간 다른 버전인 샘플 파일입니다.

$ cat testfile2
xxATGxxATG

ATGxxxATGxxx

xxATGxxxxATGxxATG

-n원래 입력에 행 번호 표시를 추가 하면 다음이 표시됩니다.

$ grep -no ATG testfile2
1:ATG
1:ATG
3:ATG
3:ATG
5:ATG
5:ATG
5:ATG

마지막으로 uniq -c다음을 사용하여 계산합니다.

$ grep -no ATG testfile2 | uniq -c
  2 1:ATG
  2 3:ATG
  3 5:ATG

이제 개수 ATG와 개수가 나온 (입력 파일의) 줄 번호가 있습니다.

다음을 사용하여 개수만 표시하도록 변환할 수도 있습니다 awk.

$ grep -no ATG testfile2 | uniq -c | awk '{print $1}'
2
2
3

awk는 $1첫 번째 필드를 나타냅니다.

답변4

정말 재미있게 즐기고 싶다면 awk다음과 같이 하세요.

echo -e "test one - test two - test three\ntest four - test five\nnope six\ntest seven"
test one - test two - test three
test four - test five
nope six
test seven
...
echo -e "test one - test two - test three\ntest four - test five\nnope six\ntest seven" | awk -v myVar="test" 'BEGIN{count=0}; {thisLine=gsub(myVar,"&"); count=count+thisLine; print "\"" myVar "\" in line " NR ": " thisLine}; END{print "Total number of \"" myVar "\": " count}'
"test" in line 1: 3
"test" in line 2: 2
"test" in line 3: 0
"test" in line 4: 1
Total number of "test": 6

분해:

echo -e "test one - test two - test three\ntest four - test five\nnope six\ntest seven" |\  ## echo -e tells bash that '\n' is a new line
awk -v myVar="test" '                                  ## -v set an awk variable
  BEGIN{
    count=0
  };                                                   ## Begins with a 'count' variable set to zero
  {                                                    ## Now, for each line...
    thisLine=gsub(myVar,"&");                          ## Set var for number of myVar in the line, since we're using it twice
    count=count+thisLine;                              ## Add number in line to total count
    print "\"" myVar "\" in line " NR ": " thisLine    ## print for the line: myVar in quotes, line number, then count in line
  };
  END{
    print "Total number of \"" myVar "\": " count      ## End with total count
  }
'

관련 정보