![如何计算多次出现的列表中的总数量](https://linux22.com/image/167498/%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97%E5%A4%9A%E6%AC%A1%E5%87%BA%E7%8E%B0%E7%9A%84%E5%88%97%E8%A1%A8%E4%B8%AD%E7%9A%84%E6%80%BB%E6%95%B0%E9%87%8F.png)
我对 bash 及其语法很陌生,因此我想知道如何对列表进行排序以获取硬盘驱动器库存的总数。
示例如下。我们有许多来自不同供应商和型号的服务器和硬盘。
你会如何根据数字而不是他们名字的出现次数来将它们数在一起?
ST8000NC0002: 8
ST900MM0168: 1
ST900MM0168: 1
ST9300603SS: 3
ST9300605SS: 4
ST9500620SS: 3
WD1003FBYX: 7
WD1500HLFS: 4
WD9001BKHG: 3
WD9001BKHG: 3
WD9001BKHG: 4
WD9001BKHG: 4
期望的输出:
ST8000NC0002: 8
ST900MM0168: 2
ST9300603SS: 3
ST9300605SS: 4
ST9500620SS: 3
WD1003FBYX: 7
WD1500HLFS: 4
WD9001BKHG: 14
答案1
awk
就是为此而生的。填充data
由第一个字段( ) 索引的数组( $1
),并累积第二个字段 ( $2
) 的值。填充数组后,使用简单的for
循环输出数据。为了方便起见,通过管道输出sort
。
awk '{data[$1]+=$2} END { for( d in data ) { print d, data[d] } }' input | sort
ST8000NC0002: 8
ST900MM0168: 2
ST9300603SS: 3
ST9300605SS: 4
ST9500620SS: 3
WD1003FBYX: 7
WD1500HLFS: 4
WD9001BKHG: 14
答案2
使用 GNU datamash
:
datamash -W -g 1 sum 2 < file
-W
使用whitspace(空格/制表符)作为字段分隔符(而不是制表符)-g 1
第一个字段上的组sum 2
第二个字段的总和值(每组)
输出:
ST8000NC0002: 8
ST900MM0168: 2
ST9300603SS: 3
ST9300605SS: 4
ST9500620SS: 3
WD1003FBYX: 7
WD1500HLFS: 4
WD9001BKHG: 14
这工作正常,因为您的输入已经在第一个字段上排序。对于未排序的输入,添加选项-s
以在分组之前对输入进行排序。