유전자 서열이 포함된 파일이 있습니다. 예를 들면 다음과 같습니다.
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입니다. 따라서 이러한 행의 조건은NF
false로 평가되어 효과적으로 건너뜁니다.)
답변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
}
'