awk - 四舍五入到小数点后 2 位

awk - 四舍五入到小数点后 2 位

我正在使用以下 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%

参考这个帖子:https://stackoverflow.com/questions/18696096/awk-calculate-sum-of-2nd-column-and-percentage-wrt-sum-and-print

我试图将其集成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)

相关内容