如何使用awk对单个标识符对应的第二列数值求和并将结果转为对应位数的星号输出?
没问题,我来帮你搞定这个awk处理需求!
首先得说下你之前用的awk '{gsub("12", "**"); print}' test.txt为什么不对——这个命令只是在每行文本里把字符串"12"替换成"",完全没做分组求和**的核心操作,自然达不到你的要求。
正确的思路应该是先遍历文件,用awk的数组对每个标识符的数值做累加,等所有行处理完后,再把每个总和转换成对应位数的星号输出。这里给你两个可行的awk命令:
方法一:用截取长星号字符串的方式生成星号
awk '{sum[$1] += $2} END {for (key in sum) { star_count = length(sum[key]) stars = substr("****************************************", 1, star_count) printf "%s : %s\n", key, stars }}' test.txt
方法二:用循环拼接星号
awk '{sum[$1] += $2} END {for (key in sum) { stars = "" for (i=1; i<=length(sum[key]); i++) { stars = stars "*" } printf "%s : %s\n", key, stars }}' test.txt
代码解释:
{sum[$1] += $2}:这是处理每一行的核心逻辑——把当前行第二列的数值,累加到以第一列标识符为键的数组sum里。比如遇到a 10时sum["a"]变成10,再遇到a 2时就会变成12。END { ... }:END块里的代码会在所有行都处理完成后才执行,这时候sum数组已经存好了每个标识符的最终总和。length(sum[key]):计算当前总和的数字位数,比如12的长度是2,1的长度是1。- 生成星号的两种方式:
- 方法一是提前准备一个足够长的星号字符串,截取前
star_count个字符,简单高效。 - 方法二是通过循环逐个拼接星号,逻辑更直观。
- 方法一是提前准备一个足够长的星号字符串,截取前
用你提供的测试文件运行后,会得到符合预期的输出(默认是每行一个结果,如果想要一行输出,可以把printf "%s : %s\n"改成printf "%s : %s ", key, stars,最后再加个print ""换行):
a : ** b : ** c : *
内容的提问来源于stack exchange,提问作者meri
相关产品推荐
相关产品推荐

