首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >awk:不过滤的非零数筛选器

awk:不过滤的非零数筛选器
EN

Stack Overflow用户
提问于 2018-07-04 23:44:58
回答 1查看 87关注 0票数 0

我以前曾使用awk将包含大部分为零的庞大数据表简化为只有有趣的行(那些没有太多零的表)的较小的表,如下所示:

代码语言:javascript
复制
awk -F '\t' '{count=0} {for(i=2; i<30; i++) if($i==0) count++} {if(count<5) print $0}' BigTable > SmallerTable 

现在,我想过滤一个类似的表,在大多数“女性”列中查找具有非零值的行,在大多数“男性”列中查找零。我尝试使用相同的awk逻辑,但我的代码返回输入文件的所有行。

代码语言:javascript
复制
#! /usr/bin/awk -f 
FS="\t"
{countF=0} {for(i=2; i<7; i++) if($i==0) countF++} 
# count zeros in female columns 2-6
{countM=0} {for(i=7; i<12; i++) if($i==0) countM++} 
# count zeros in male columns 7-12
{if (countF<2 && countM>3) {print $0}}
# if fewer than 2/5 females AND more than 3/5 males are zero, print line

我的输入文件是这样开始的:

代码语言:javascript
复制
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN F_CR1   F_CR2   F_CR3   F_CR4   F_CR6   M_CR10  M_CR5   M_CR7   M_CR8   M_CR9
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 14727   13526   13318   13862   11040   18975   21411   20079   16285   15611
CCGGTGTGACAACTGTAGTGAACTCAGCTCA 23  32  26  15  28  28  42  29  8   22
AACCAAATCTACAAACAGGAGATGTTGTTCT 107 110 118 106 95  100 121 132 92  90
GAAATAGAACAGGCCTGGAAGCCATGTCAAA 15  15  16  12  11  31  23  19  9   28

我把打印行的语法搞砸了吗?任何建议都非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-05 03:43:13

FS="\t"更改为BEGIN{FS="\t"}。现在,该赋值的结果是一个真正的条件,它调用了打印每一行的默认操作。

然后将shell脚本更改为:

代码语言:javascript
复制
/usr/bin/awk '
BEGIN { FS="\t" }
{
    # count zeros in female columns
    countF=0
    for(i=2; i<=6; i++) {
        if ($i==0) {
            countF++
        }
    }

    # count zeros in male columns
    countM=0
    for(; i<=NF; i++) {
        if ($i==0) {
            countM++
        }
    }
}
# if fewer than 2/5 females AND more than 3/5 males are zero, print line
countF<2 && countM>3
' "$@"

因此,如果/当您需要将shell args分离为awk args和awk变量赋值时,它会更像awk,并且更容易在以后进行增强(shebang对此并不有用)。

还可以考虑缩写它并删除硬编码的男性/女性限制,而是从标题行中获取它们:

代码语言:javascript
复制
/usr/bin/awk '
BEGIN { FS="\t" }
FNR==1 {
    for (i=2; i<=NF; i++) {
        sub(/_.*/,"",$i)
        gender[i] = $i
    }
    next
}
{
    for (i=2; i<=NF; i++) {
        count[gender[i]] += ($i==0)
    }
}
count["F"]<2 && count["M"]>3
' "$@"

上面的测试是未经测试的,因为您没有为我们提供可供测试的预期输出。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51181823

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档