使用awk命令计数

时间:2014-03-03 20:41:56

标签: linux awk count

我有fileA.txt,下面显示了几行:

AA
BB
CC
DD  
EE

我有fileB.txt,它的文字如下所示:

Group  col2   col3    col4
1    pp    4567    AA,BC,AB
1    qp    3428    AA
2    pp    3892    AA
3    ee    28399   AA
4    dd    3829    BB,CC
1    dd    27819   BB
5    ak    29938   CC

对于fileA.txt中的每一行,它应该根据fileB.txt中的column1计算它在fileB.txt中的存在次数。

示例输出应如下所示:

AA    3
BB    2
CC    2

AA存在4次,但它在组“1”中存在两次。如果它在column1中的同一组中出现多次,则只应计数一次,因此在上面的输出中AA计数为3.

使用awk或任何其他oneliners的任何帮助?

3 个答案:

答案 0 :(得分:1)

这是一个应该有效的awk单行:

awk '
NR==FNR && !seen[$4,$1]++{count[$4]++;next}
($1 in count){print $1,count[$1]}' fileB.txt fileA.txt

阐释:

  • NR==FNR&&!seen[$4,$1]++模式仅在第1列未被捕获时才为真。对于所有重复捕获,我们不增加计数器。
  • $1 in count在数组中查找第一个文件列1的存在。如果它存在,我们打印计数。

输出

$ awk 'NR==FNR && !seen[$4,$1]++{count[$4]++;next}($1 in count){print $1,count[$1]}' fileB.txt fileA.txt
AA 3
BB 2
CC 1

根据修改后的问题进行更新:

awk '
NR==FNR {
  n = split($4,tmp,/,/);
  for(x = 1; x <= n; x++) {
    if(!seen[$1,tmp[x]]++) {
      count[tmp[x]]++
      }
    }
  next
}
($1 in count) {
    print $1, count[$1]
}' fileB.txt fileA.txt

<强>输出:

AA 3
BB 2
CC 2

答案 1 :(得分:0)

Pure bash(4.0或更新版):

#!/bin/bash

declare -A items=()

# read in the list of items to track
while read -r; do items[$REPLY]=0; done <fileA.txt

# read fourth column from fileB and increment for each match
while read -r _ _ _ item _; do
  [[ ${items[$item]} ]] || continue    # skip unrecognized values
  items[$item]=$(( items[$item] + 1 )) # otherwise, increment
done <fileB.txt

# print output
for key in "${!items[@]}"; do          # iterate over keys
  value="${items[$key]}"               # look up values
  printf '%s\t%s\n' "$key" "$value"    # print them together
done

答案 2 :(得分:0)

一个简单的awk单行。

awk 'NR>FNR{if($0 in a)print$0,a[$0];next}!a[$4,$1]++{a[$4]++}' fileB.txt fileA.txt

请注意文件的顺序。