总结awk中的文本文件

时间:2018-03-24 15:36:22

标签: awk fasta

我有一系列字符,我希望将每个序列从开头到结尾分成3-characters class。并获得每个班级的计数。这是2 IDs的字符序列的一个小例子。

>ID1
ATGTCCAAGGGGATCCTGCAGGTGCATCCTCCGATCTGCGACTGCCCGGGCTGCCGAATA
TCCTCCCCGGTGAACCGGGGGCGGCTGGCAGACAAGAGGACAGTCGCCCTGCCTGCCGCC
>ID2
ATGAAACTTTCACCTGCGCTCCCGGGAACAGTTTCTGCTCGGACTCCTGATCGTTCACCT
CCCTGTTTTCCCGACAGCGAGGACTGTCTTTTCCAACCCGACATGGATGTGCTCCCAATG
ACCTGCCCGCCACCACCAGTTCCAAAGTTTGCACTCCTTAAGGATTATAGGCCTTCAGCT

这是ID1输出的一个小例子。我想为输入文件中的所有IDs获取相同的输出(每行ID的字符行都在下一行)。下一个ID的计数就在第一个之后,依此类推。

ID1_3nt count
ATG 1
TCC 3
AAG 2
GGG 2
ATC 2
CTG 3
CAG 1
GTG 2
CAT 1
CCT 2
CCG 3
TGC 3
GAC 2
GGC 1
CGA 1
ATA 1
AAC 1
CGG 2
GCA 1
AGG 1
GCC 3
ACA 1
GTC 1

我试过这段代码:

awk '{i=0; printf ">%s\n",$2; while(i<=length($1)) {printf "%s\n", substr($1,i,3);i+=3}} /,substr,/ {count++}' | awk 'END { printf(" ID_3nt: %d",count)}

但没有回复我想要的东西。你知道怎么改进吗?

2 个答案:

答案 0 :(得分:0)

这个基于patsplit()的实施怎么样?

#! /usr/bin/awk -f

# initialize publicly scoped vars...
function init() {
    split("", idx) # index of our class (for ordering)
    split("", cls) # our class name
    split("", cnt) # num of classes we have seen
    sz = 0         # number of classes for this ID
}

# process a class record
function proc(    i, n, x) {
    # split on each 3 characters
    n = patsplit($0, a, /.../)
    for (i=1; i<=n; ++i) {
        x = a[i]
        if (x in idx) {
            # if this cls exists, just increment the count
            ++cnt[idx[x]]
        } else {
            # if this cls doesn't exist, index it in
            cls[sz] = x
            cnt[sz] = 1
            idx[x] = sz++
        }
    }
}

# spit out class summary
function flush(    i) {
    if(!sz)
        return
    for(i=0; i<sz; ++i)
        print cls[i], cnt[i]
    init()
}

BEGIN {
    init()
}

/^>ID/ {
    flush()
    sub(/^>/, "")
    print $0 "_3nt count"
    next
}

{
    # we could have just inlined proc(), but using a function
    # provides us with locally scoped variables
    proc()
}

END {
    flush()
}

答案 1 :(得分:0)

$ cat tst.awk
sub(/^>/,"") { if (NR>1) prt(); name=$0; next }
{ rec = rec $0 }
END { prt() }
function prt(    cnt, class) {
    while ( rec != "" ) {
        cnt[substr(rec,1,3)]++
        rec = substr(rec,4)
    }
    print name "_3nt count"
    for (class in cnt) {
        print class, cnt[class]
    }
}

$ awk -f tst.awk file
ID1_3nt count
ACA 1
AAC 1
CGA 1
CAT 1
GTG 2
CAG 1
GGG 2
CCG 3
CCT 2
GCA 1
ATA 1
GAC 2
AAG 2
GCC 3
ATC 2
TCC 3
CGG 2
CTG 3
GTC 1
AGG 1
GGC 1
TGC 3
ATG 1
ID2_3nt count
AAA 1
CCC 3
ACA 1
GTG 1
TTT 2
TGT 2
GTT 2
ACC 1
CCG 2
CTC 3
CCT 4
GCA 1
AAG 2
GAC 3
TCA 3
AGC 1
ACT 1
CGT 1
CGG 1
CTT 3
TAT 1
CAA 1
GAG 1
GAT 3
GGA 1
AGG 1
TGC 1
CCA 5
TTC 1
GCT 2
TCT 1
GCG 1
ATG 3