使用linux / bash计算列元素

时间:2015-04-01 01:58:48

标签: arrays linux bash unix scripting

我有许多制表符分隔文件,其数据有点像这样

Header1               Header2....... Headern
Cat Bat                mat pat
Hat                     rat
Rat                  [Not Applicable]
[Not Available]      [Not Applicable]

我需要计算每个标头的有效行数。 无效的条目是[不可用],[不适用]等。 我试图在一个数组中获取标题元素。一切都很好,直到这里。 但是,我发现难以计算每个标题。我还使用数组来存储标题的行值。但问题是数组存储[不作为一个不同的元素和可用]作为其他元素。此外,对于第一个标题,' Cat Bat'应该是一个条目,但数组也可能存储2个条目。

1 个答案:

答案 0 :(得分:1)

让我们从这个以制表符分隔的文件开始:

$ cat file
Header1         Header2
Cat Bat         mat pat
Hat             rat
Rat             [Not Applicable]
[Not Available] [Not Applicable]

对于每列,以下内容计算不以[Not A开头的条目:

$ awk -F'\t' 'NR==1{for (i=1;i<=NF;i++)h[i]=$i;next} {for (i=1;i<=NF;i++)c[i]+=($i !~ /[[]Not A/)} END{for (i=1;i<=NF;i++)print h[i],c[i]}' file
Header1 3
Header2 2

如何运作

  • -F'\t'

    这会将字段分隔符设置为选项卡。

  • NR==1{for (i=1;i<=NF;i++)h[i]=$i;next}

    对于第一行,这将保存数组h中的所有标题,然后跳过其余命令并跳转到next行。

  • {for (i=1;i<=NF;i++)c[i]+=($i !~ /[[]Not A/)}

    对于第一行之后的所有行,如果列c[i]的值不以i开头,则会遍历每列并递增[Not A

  • END{for (i=1;i<=NF;i++)print h[i],c[i]}

    读完最后一行后,会打印出结果。

更新

假设除了[Not Applicable][Not Available]之外,我们还要忽略[unavailable](注意:全部小写)。在这种情况下,我们对正则表达式稍作修改:

awk -F'\t' 'NR==1{for (i=1;i<=NF;i++)h[i]=$i;next} {for (i=1;i<=NF;i++)c[i]+=($i !~ /[[](Not A|unavailable)/)} END{for (i=1;i<=NF;i++)print h[i],c[i]}' file