我正在使用以下 awk 命令计算文件列中每个项目的百分比:
awk '{a[NR]=$2;x+=(b[NR]=$2);c[NR]=$1}END{while(++i<=NR)print c[i]"\t"a[i]"\t"100*b[i]/x"%"}' file.txt > out_file.txt
文件.txt
N 38668442
V 14008521
ADJ 16112215
输出文件.txt
N 38668442 56,213%
V 14008521 20,3644%
ADJ 16112215 23,4226%
但是,我希望 out_file.txt 中的百分比四舍五入到小数点后 2 位。
所需的 out_file.txt
N 38668442 56,21%
V 14008521 20,37%
ADJ 16112215 23,42%
我试图将其集成printf "%s,%d,%0.2f%\n
到我的代码中,即使减少参数并将表达式限制为,也会引发参数错误%0.2f%\n
。
awk '{a[NR]=$2;x+=(b[NR]=$2);c[NR]=$1}END{while(++i<=NR)printf "%s,%d,%0.2f%\n",c[i]"\t"a[i]"\t"100*b[i]/x"%"}' file.txt > out_file.txt
也bc
没有成功。为什么它没有产生所需的输出?在我看来,它应该有效,因为我printf "%0.2f\n"
在有关同一问题的几篇文章中找到了这种表达方式。我错过了一些琐碎的事情吗?
我非常感谢任何帮助或建议!
答案1
您误解了命令的语法printf
(该命令的语法与底层C
函数的语法非常接近:例如man 3 printf
以获取完整文档)。
printf
采取格式字符串由一系列格式说明符和其他文字字符,后跟尽可能多的逗号分隔的参数,以填充给定的格式。在您的命令中
printf "%s,%d,%0.2f%\n",c[i]"\t"a[i]"\t"100*b[i]/x"%"
你告诉它需要 3 个值(a %s
、a%d
和 a %0.2f
),但只给它一个连接的字符串参数c[i]"\t"a[i]"\t"100*b[i]/x"%"
。因此,在分配期间它将用尽参数。
你可能想的是
printf "%s\t%d\t%0.2f%%\n", c[i], a[i], 100*b[i]/x
(制表符位于格式字符串内;%%
对应于文字%
,即防止%
被解释为另一个格式说明符的开头)。
答案2
您还可以使用这样的函数来修复 awk 将 0.5 等向下舍入的烦人事实。
function round(number, nDecimals,
coef, i)
{
coef = 1
for (i = 1; i <= nDecimals; ++i)
{
coef *= 10
}
number *= coef
number >= 0 ? number += 0.5 : number -= 0.5
number = int(number)
number /= coef
return number
}
然后,您可以编写如下代码来打印四舍五入到小数点后两位的输入:
print round($0, 2)