我正在努力寻找一种方法来总结一行数字。
我有以下代码。
lshw -class disk -class storage | grep size: | cut -d "(" -f2 | cut -d ")" -f1
这给了我结果
2TB
2TB
2TB
2TB
2TB
2TB
在我的另一台机器上:
500GB
1TB
1TB
有没有办法总结这些?我需要保留 GB 或 TB
我完全可以用 GB 来表示,或者只在有超过 2 个结果时才将这些结果相加?我有多台机器,我应该在其中运行此命令。有些有 5 个硬盘,有些只有 1 个。
答案1
使用xml
或json
输出格式提供的工具来解析可用的工具可能会更容易:
lshw -quiet -class disk -class storage -xml |
xmlstarlet sel -t -v //size -n |
paste -sd + - |
bc |
numfmt --to=si --suffix=B
格式:
lshw -quiet -class disk -class storage -json |
jq '[.children[]|.size]|add' |
numfmt --to=si --suffix=B
即使您没有xml
/json
解析工具,以这些格式输出仍然是更好的选择,因为您可以获得确切的字节数,因此在从/到人类可读格式转换时不会丢失信息。
然后,您可以恢复到一些基于启发式的解析,例如默认输出格式。使用 GNU grep
:
lshw -quiet -class disk -class storage -json |
grep -Po '"size" : \K\d+' |
paste -sd + - |
bc |
numfmt --to=si --suffix=B
--round=nearest
向 GNU添加选项numfmt
(自 8.21 (2013) 起在 GNU coreutils 中)以舍入到最接近的数字而不是向上舍入。另请参阅--format=%.3f
以获得更高的精度。
答案2
sed
+numfmt
解决方案:
lshw -class disk -class storage \
| sed -n '/size:/ s/.*(\([0-9]*.*[KMGT]\)B)/\1/p' \
| numfmt --from si | paste -sd+ - | bc | numfmt --to si --suffix B
paste -sd+ - | bc
也可以替换为awk '{ sum+=$1 }END{ print sum }'