计算每列中的行数

Counting the number of lines in each column

是否可以统计文件每一列的行数?例如,我一直在尝试使用 awk 来分隔分号上的列,分别指定每一列,然后使用 wc 命令来计算该列中出现的所有事件。
对于下面的命令,我试图在不计算空行的情况下查找第 3 列中的项目数。不幸的是,这个命令只对整个文件进行计数。我可以将该列移至另一个文件并对该文件进行计数,但我只想知道是否有更快的方法来解决这个问题?

awk -F ';' '{print }' file.txt | wc -l

数据文件格式

; 1 ; 2 ; 3 ; 4 ; 5 ; 6 ;  
; 3 ; 4 ; 5 ; 6 ;   ; 4 ;  
;   ; 3 ; 5 ; 6 ; 9 ; 8 ;  
; 1 ; 6 ; 3 ;   ;   ; 4 ;  
; 2 ; 3 ;   ; 3 ;   ; 5 ;  

需要示例输出

Column 1 = 4 aka(1 + 3 + 1 + 2)  
Column 2 = 5  
Column 3 = 4  
Colunm 4 = 4  
Column 5 = 2  
Column 6 = 5 

使用数组为每个字段单独计数,然后在完成后打印总数:

$ awk -F' *; *' '{ for (i = 2; i < NF; ++i) if ($i != "") ++count[i] } 
  END { for (i = 2; i < NF; ++i) print "Column", i-1, "=", count[i] }' file
Column 1 = 4
Column 2 = 5
Column 3 = 4
Column 4 = 4
Column 5 = 2
Column 6 = 5
  • 设置字段分隔符以消耗分号以及任何周围的 spaces。
  • 遍历每个字段(第一个和最后一个字段除外,它们始终为空)并为非空字段增加一个计数器。
    • 使用 if ($i) 很诱人,但对于包含 0.
    • 的列,这会失败
  • 打印 END 块中的计数,从 1 开始偏移 -1 而不是 2

这里的一个假设是每行的列数在整个文件中是统一的,因此最后一行的 NF 可以安全地用在 END 块中。


略有不同,使用更简单的字段分隔符:

$ awk -F';' '{ for (i = 2; i < NF; ++i) count[i] += ($i ~ /[^ ]/) } 
  END { for (i = 2; i < NF; ++i) print "Column", i-1, "=", count[i] }' file
如果第 i 字段中存在任何非 space 字符,

$i ~ /[^ ]/ 等于 1,否则 0