计算给定另一个字段值的字段的出现次数

时间:2013-11-27 18:48:35

标签: bash unix design-patterns scripting awk

我有一个制表符分隔表,如下面的

402 Tea Bags    4
403 Tea Bags    4
404 Tea Bags    3
405 Milk    3
406 Sugar   4
407 Sugar   3
408 Sugar   4
409 Milk    4
410 Milk    3
411 Milk    3

我想在给定第三场条件的情况下计算第二场的出现次数。当第三场为3和4时茶袋的出现次数示例

$3==4 && $2=="Tea Bags"; count ++

第三个字段中可以有两个以上的数字,第二个字段中可以有三个以上的选项。

然后我想最终将它们列为

Tea Bags    4  2
Tea Bags    3  1
Milk    3  3
Milk    4  1
Sugar   4  2
Sugar   3  1

我可以使用

在awk中单独计算它们
awk -F "\t" '{for(i=1; i<=NF; i++) 
    if(($i=="Tea Bags" && ($(i+1)==3))) c++ } 
   END{ print c }' file.txt 

但是,我想应该有一个更短,更有效的方法,因为我有一个非常大的文件。谢谢!

4 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

BEGIN {FS="\t"; OFS="\t"}

{a[$2,$3]++}

END {
    for (k in a) {
        split(k, p, SUBSEP)
        print p[1], p[2], a[k]
    }
}

或者写(以避免分割/ SUBSEP)

BEGIN {FS="\t"; OFS="\t"}

{a[$2 OFS $3]++}

END {
    for (k in a) {
        print k, a[k]
    }
}

答案 1 :(得分:1)

使用此awk命令:

awk -F "\t" '{k=$2 FS $3; if (!(k in a)) s[j++]=k; a[k]++} 
             END {for (i=0; i<length(s); i++) print s[i], a[s[i]]}' OFS="\t" file

Tea Bags        4       2
Tea Bags        3       1
Milk    3       3
Sugar   4       2
Sugar   3       1
Milk    4       1

答案 2 :(得分:1)

这个awk单行怎么样:

 awk '{sub(/\S*\t/,"");a[$0]++}END{for(x in a)print x, a[x]}' file

答案 3 :(得分:0)

使用关联数组的Bash解决方案:

declare -A count

while IFS=$'\t'; read col1 col23 ; do
  ((count[$col23]++))                 # use col 2 and 3 as key
done < "$infile"

for key in "${!count[@]}"; do
  echo -e "$key\t${count[$key]}"
done

输出:

Tea Bags    4   2
Tea Bags    3   1
Sugar   4   2
Sugar   3   1
Milk    4   1
Milk    3   3