【问题标题】:Counting the number of lines in each column计算每列的行数
【发布时间】:2018-07-16 11:40:37
【问题描述】:

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

awk -F ';' '{print $3}' 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 printing wc


【解决方案1】:

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

$ 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
  • 设置字段分隔符以使用分号以及任何周围的空格。
  • 遍历每个字段(第一个和最后一个字段除外,它们始终为空)并为非空字段增加一个计数器。
    • 使用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

如果ith 字段中存在任何非空格字符,则$i ~ /[^ ]/ 等于1,否则为0

【讨论】:

  • 不错的解决方案,但我相信如果你这样做可能会更短count[i]+=($i != "")
  • @kvantour 谢谢,我编辑添加了一个基于类似原则的替代方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
  • 2018-10-03
相关资源
最近更新 更多