Chinaunix

标题: 有条件计数 [打印本页]

作者: 怿_mao44    时间: 2012-06-12 11:46
标题: 有条件计数
本帖最后由 怿_mao44 于 2012-06-12 13:43 编辑

输入文件:
  1. aaa        1        12        123        AA1        AA2        pre-abc
  2. aaa        1        21        321        AA1        AA2        pre-abc
  3. bbb        2        23        234        BB1        BB2        pre-abc
  4. bbb        3        34        345        BB1        BB2        post-abc
  5. aaa        4        45        456        AA1        AA3        post-abc
  6. abb        5        56        567        AA1        AA2        post-abc
  7. abb        6        67        678        AA1        AA2        pre-abc
  8. bbb        2        23        234        BB3        BB4        post-abc
  9. bbb        2        23        234        AA1        AA2        pre-abc
  10. bbb        4        45        456        AA1        AA2        post-abc
复制代码
目的:,以第五,六列为一个单位,对第一列的内容计数

计数条件:
1.第一列内容相同的时候,还要比较对应的每一行中第五,六列内容也必须同时相同
2.对应的记录中第七列必须同时存在"pre-abc"和"post-abc"
3.符合此条件的第一列记录则,记为1
(以aaa为例,存在有重复的记录,且对应有"pre-abc"和"post-abc"同时存在,但是对应[AA1 AA2]和[AA1 AA3]并不相同,则不能计数。)

输出结果:
输入文件中,对应“AA1        AA2”的记录中,有“abb,bbb”符合条件,所以记为两次;而只有“bbb”对应“BB1        BB2”,故只记做1次
  1. AA1        AA2        2
  2. BB1        BB2        1
复制代码

作者: 英语盲学linux    时间: 2012-06-12 12:36
  1. awk '{a[$1$5,$6]=a[$1$5,$6]$7}END{for(i in a) if(a[i]=="-+" || a[i]=="+-") ++b[substr(i,length(i)-6,7)];for(k in b)print k,b[k]}'
复制代码

作者: yinyuemi    时间: 2012-06-12 13:13
回复 1# 怿_mao44

gawk4.0.0
  1. gawk '{p=$NF~"+"?1:-1;a[$1][$5 FS $6]+=p}END{for(i in a)for(j in a[i])if(a[i][j]==0)b[j]++;for(x in b)print x,b[x]}'
复制代码

作者: 怿_mao44    时间: 2012-06-12 13:42
回复 3# yinyuemi


    也许是版本不同,或者其他原因,并不能实现

$ gawk --v
GNU Awk 3.1.5


或许时候由于实际数据中,第七列,并不是简单的+/-,而是一段字符所以有影响
作者: 怿_mao44    时间: 2012-06-12 13:45
回复 2# 英语盲学linux


    实际操作中,并不是单纯+/-,而是一些符合字符串,可能有影响,导致,并无法得到结果呢
作者: yinyuemi    时间: 2012-06-12 13:57
回复 4# 怿_mao44

+/-的问题,根据你的实际数据改吧
  1. awk '{p=$NF~"+"?1:-1;a[$1"|"$5 FS $6]+=p}END{for(i in a)if(a[i]==0)b[gensub(/.*\|(.*)/,"\\1",1,i)]++;for(x in b)print x,b[x]}'
复制代码

作者: 怿_mao44    时间: 2012-06-12 14:15

  1. $ more file |sort|uniq >test        ##对输入文件去重复
  2. $ cut -f 1,5,6 test|uniq -d >test1    ##只提取第1列,和第5,6列,然后只提取有重复的记录,因为之前已经对全文件去重复过了,所以此时的重复记录,就是同时对应不同第7列的记录
  3. $ cut -f 2,3 test|sort|uniq -c >test    ##在对第2,3列,其实为输入文件中的5,6列排序计数
复制代码

    好吧,这是我最初想的巨2分析流程,总觉得有一丝扭曲
作者: 怿_mao44    时间: 2012-06-12 14:29
回复 6# yinyuemi


    由于实际数据不同,真正修改的地方就只是红色区域的么?

awk '{p=$NF~"+"?1:-1;a[$1"|"$5 FS $6]+=p}END{for(i in a)if(a==0)b[gensub(/.*\|(.*)/,"\\1",1,i)]++;for(x in b)print x,b[x]}'

但是,输出的结果我抽取了几个例子,手工查,好像有些偏差的。难道是我使用时候有问题木?
作者: 怿_mao44    时间: 2012-06-12 16:36
回复 6# yinyuemi


    知道哪里错了。。
输入文件在处理前,要先做排序去重复,除去一些完全一致的记录行,再处理
作者: rdcwayx    时间: 2012-06-12 20:48
  1. awk '{ a[$1 OFS $5 OFS $6]
  2.        if ($NF=="pre-abc") pre[$1 OFS $5 OFS $6]=1
  3.        if ($NF=="post-abc") post[$1 OFS $5 OFS $6]=1
  4.      }END{ for (i in a) if (pre[i]==1&&post[i]==1) {split(i,s,OFS);b[s[2] OFS s[3]]++}
  5.            for (i in b) print i,b[i]}' OFS="\t" infile
复制代码





欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2