【问题标题】:summarizing a text file in awk在 awk 中总结文本文件
【发布时间】:2018-09-03 03:04:14
【问题描述】:

我有一个字符序列,我想将每个序列从头到尾拆分为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)}

但没有返回我想要的。你知道如何改进吗?

【问题讨论】:

  • 当前代码有什么问题? awk 要求严格吗?
  • 它没有返回与我正在寻找的相同的输出。我正在使用 awk。
  • 它输出什么? awk 是严格要求吗?
  • @john,请解释一下 count 是如何输出的?
  • 假设输入只有ATGTCCAAGGGG,应该是4个三元组(ATGTCCAAGGGG),还是应该是10个三元组(ATGTGTGTCTCC,……GGG)?这从您的预期输出中并不清楚(需要大量计算才能得出答案)。三胞胎的顺序和计数重要吗?

标签: awk fasta


【解决方案1】:

这个基于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()
}

【讨论】:

    【解决方案2】:
    $ 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 2021-06-11
      • 2014-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多