首页 > 解决方案 > awk - 拉出对列并获取出现次数

问题描述

我有一个表模式 - 以逗号分隔的列名称。为清楚起见,我将它们放在每行一列中,如下所示

$ cat cols_name.txt
id
resp
x_amt
rate1
rate2
rate3
pay1
pay2
rate_r1
rate_r2
x_rate1
x_rate2
x_rate3
x_rate_r1
x_rate_r2
x_pay1
x_pay2
rev1
x_rev1

我需要找出匹配列对( pay1 -> x_pay1 )的对,并将它们一起列为中间输出,如下所示

x_rate1 rate1
x_rate2 rate2
x_rate3 rate3
x_pay1 pay1
x_pay2 pay2
x_rate_r1 rate_r1
x_rate_r2 rate_r2
x_rev1 rev1

然后最后将频率打印为

 pay 2
 rate 3
 rate_r 2
 rev 1

在我尝试获取中间输出时,下面的 awk 命令不起作用。

awk ' NR==FNR { if( $1~/^x_/ ) a[$1]=1 ; next }  $1~/"x_" a[$1]/ { print $0 } ' cols_name.txt cols_name.txt

它没有打印任何东西。你能帮忙解决吗

标签: linuxawk

解决方案


awk这是完成它的单通道:

 awk '/^x_/ {xk[$0]; next} {s=$0; sub(/[0-9]+$/, "", s); xv[$0]=s} END {for (i in xv) if ("x_" i in xk) {print "x_" i, i; ++fq[xv[i]]}; print "== Summary =="; for (i in fq) print i, fq[i]}' file

x_rev1 rev1
x_rate1 rate1
x_rate2 rate2
x_rate3 rate3
x_rate_r1 rate_r1
x_pay1 pay1
x_rate_r2 rate_r2
x_pay2 pay2
== Summary ==
rate_r 2
rate 3
rev 1
pay 2

更易读的形式:

awk '
/^x_/ {
   xk[$0]
   next
}
{
   s = $0
   sub(/[0-9]+$/, "", s)
   xv[$0] = s
}
END {
   for (i in xv)
      if ("x_" i in xk) {
         print "x_" i, i
         ++fq[xv[i]]
      }
   print "== Summary =="
   for (i in fq)
      print i, fq[i]
}' file

推荐阅读