DNA 서열 계산

DNA 서열 계산

공백으로 구분된 DNA 서열이 있습니다. 공백을 제거하고 공백 문자 없이 시퀀스 수를 반환해야 합니다. 이 작업을 수행하는 방법에 대한 도움이 있습니까? bash와 함께 터미널을 사용하고 있습니다.

예를 들어 시퀀스는 다음과 같습니다.

GTCGATTGCAAGGATCCGCATGGGATAAAGGAATCGCAGTTCGAACAGGCAATGCCGCAG
CTATGATAGGACATCTCTTGGAGACACCTATTAATGTTTCAGAAACGGATACCTTGGTTG
TCCAGTACGAAATTAAGTTGGACAATTCTTTGACGTGCGGC
CTATATTAAAATTGTGGGTACATCACTCTCTTACCTGAGAATTCCAACAGAGCAGGACGC
TAACCCAGTGTCTATACCAGTCTGTGGCTTTGAAAGATTAGACACATTTCTGGATGAATT
TTCAAATTCTAAATTGATCGTTCAGTCTACACTAAGACATTCGTACGTTAGTCTTGAGAA

공백을 제거하고 정확히 몇 개의 염기가 있는지 계산하고 싶습니다. 또는 A, C, G 또는 T가 몇 개나 있는지 계산하고 공백을 계산하지 않고 추가할 수 있습니다.

답변1

GNU awk를 사용하는 다중 문자 RS 및 RT:

$ awk -v RS='[^\n]' 'RT{cnt[RT]++} END{for (base in cnt) print base, cnt[base]}' file
A 101
C 68
T 98
G 74

귀하의 설명에서 "기본"은 귀하의 예에서 개행 문자가 아닌 모든 문자라고 가정합니다.

답변2

빈 줄이나 후행 공백 등이 없다고 가정하면 fold개별 문자 스트림을 생성한 다음 sort결합하여 uniq -c다음을 사용하여 각 문자의 수를 계산할 수 있습니다.

$ fold -w 1 file | sort | uniq -c
 101 A
  68 C
  74 G
  98 T

입력에 정크 공백 문자가 있는 경우 초기 tr단계를 사용하여 이러한 문자를 제거합니다.

$ tr -d -c 'ACGT' <file | fold -w 1 | sort | uniq -c
 101 A
  68 C
  74 G
  98 T

여기의 명령은 , 또는 를 제외한 tr입력의 모든 문자를 제거합니다 .ACGT

sort | uniq -c파이프 끝에 있는 비트는 awk입력에서 각 문자의 발생 횟수를 세고 다음을 보고하는 단일 명령 으로 대체될 수 있습니다 .

$ tr -d -c 'ACGT' <file | fold -w 1 | awk '{ count[$0]++ } END { for (ch in count) printf "%4d %s\n", count[ch], ch }'
 101 A
  68 C
  74 G
  98 T

그러나 우리가 그것을 도입하려고 한다면 awk, 그것을 제거하는 것이 나을 수도 있습니다 fold:

$ tr -d -c 'ACGT' <file | awk '{ for (i = 1; i <= length; ++i) count[substr($0,i,1)]++ } END { for (ch in count) printf "%4d %s\n", count[ch], ch }'
 101 A
  68 C
  74 G
  98 T

...다음과 같을 수도 있습니다 tr:

$ awk '{ gsub("[^ACGT]", ""); for (i = 1; i <= length; ++i) count[substr($0,i,1)]++ } END { for (ch in count) printf "%4d %s\n", count[ch], ch }' file
 101 A
  68 C
  74 G
  98 T

awk아름답게 인쇄된 코드 :

{
    gsub("[^ACGT]", "")  # removes anything not A, C, G, or T
    for (i = 1; i <= length; ++i)
        count[substr($0, i, 1)]++
}
END {
    for (ch in count) {
        printf "%4d %s\n", count[ch], ch
    }
}

gsub()대신 첫 번째 블록(입력의 각 줄을 구문 분석)을 다시 작성하여 사용할 수 있습니다 substr().

{
    count["A"] += gsub("A", "A")
    count["C"] += gsub("C", "C")
    count["G"] += gsub("G", "G")
    count["T"] += gsub("T", "T")
}
END {
    for (ch in count) {
        printf "%4d %s\n", count[ch], ch
    }
}

...하지만 중첩된 코드가 약간 줄어든 것 외에는 이전 코드에 비해 크게 개선되지는 않을 것입니다(일부 사용자의 가독성에 도움이 되지 않는 한).

답변3

Perl 하나의 라이너를 사용하십시오.

perl -F'' -e '
    BEGIN{my %h}
    map { /\S/ and $h{$_}++ } @F;
    END{print map { "$_ $h{$_}\n" } keys %h}
' file

산출

C 68
A 101
G 74
T 98

답변4

사용행복하다(이전 Perl_6)

raku -e '.say for slurp.comb(/\S/).Bag.pairs;' 

예제 출력:

G => 74
T => 98
A => 101
C => 68

또는 탭으로 구분된 출력( .say으로 변경 .put):

~$ raku -e '.put for slurp.comb(/\S/).Bag.pairs;' file
G   74
A   101
T   98
C   68

출력을 정렬해야 하는 경우 .sort끝에 다음을 추가하세요.

~$ raku -e '.put for slurp.comb(/\S/).Bag.pairs.sort;' file
A   101
C   68
G   74
T   98

또는 가장 높은 뉴클레오티드 수를 기준으로 정렬합니다.

~$ raku -e '.put for slurp.comb(/\S/).Bag.pairs.sort: -*.value;' file
A   101
T   98
G   74
C   68

아니면 그냥 세어보세요 (글꼴 없음공백):

~$ raku -e '.put for slurp.comb(/\S/).elems;' file
341

마지막으로, 매우 큰 파일로 작업하는 경우 더 나은 메모리 관리를 위해 lines.join대신 을 사용해 볼 수 있습니다 .slurp


입력 예:

GTCGATTGCAAGGATCCGCATGGGATAAAGGAATCGCAGTTCGAACAGGCAATGCCGCAG
CTATGATAGGACATCTCTTGGAGACACCTATTAATGTTTCAGAAACGGATACCTTGGTTG
TCCAGTACGAAATTAAGTTGGACAATTCTTTGACGTGCGGC
CTATATTAAAATTGTGGGTACATCACTCTCTTACCTGAGAATTCCAACAGAGCAGGACGC
TAACCCAGTGTCTATACCAGTCTGTGGCTTTGAAAGATTAGACACATTTCTGGATGAATT
TTCAAATTCTAAATTGATCGTTCAGTCTACACTAAGACATTCGTACGTTAGTCTTGAGAA

https://raku.org

관련 정보