在Bash中使用awk和printf

4

我正在尝试获取过去5分钟平均负载的四舍五入数值。以下是我的命令:

 uptime | awk -F, '{print $5}'|printf "%.0f\n"

看起来不正确,因为它总是给我0。

如果我尝试在awk和printf之间使用变量作为中间变量,那么就是正确的。

 avgload=$(uptime | awk -F, '{print $5}')

 printf "%.0f\n" $avgload

第一次尝试有什么问题吗?

谢谢和问候!

更新:

为了获取过去5分钟的平均负载,这是我在Linux服务器(Kubuntu)上使用uptime命令的输出:

$ uptime
13:52:19 up 29 days, 18 min, 15 users, load average: 10.02, 10.04, 9.58

我的笔记本电脑(Ubuntu)上也是类似的:

`$ uptime

13:53:58 up 3 days, 12:02, 8 users, load average: 0.29, 0.48, 0.60 `

这就是为什么我选取第五个字段的原因。


2
请注意,问题是因为printf不接受这种方式的参数输入。您需要使用下面各种解决方案中提到的xargs或反引号。 - Will Bickford
不,只需使用awk来进行格式化。它内置了printf函数。 - Dennis Williamson
那么,运行uptime | awk -F, '{printf "%0.f\n",$5}'。 - Will Bickford
不客气。请选择一个答案作为答案,以标记此问题完成。 - Will Bickford
最好使用$(NF-1)而不是$5,因为对于较短的正常运行时间,日期和时间信息的格式不同。 - Dennis Williamson
5个回答

10

从uptime输出中,第5个逗号分隔的字段在我的系统上不存在,这就是为什么你一直得到零的原因。5分钟的正常运行时间是倒数第二个字段,所以这样可以解决:

uptime | awk '{printf "%.0f\n",$(NF-1)}'  

使用awk进行格式化而不是将其输出无必要地管道传递到另一个命令中,这是一种专业的编程技巧。 - Dennis Williamson
谢谢!(1) awk中的$(NF-1)是什么意思?(2) 第5个逗号分隔字段是我的系统运行时间,为5分钟。请参见我对OP的更新。你的系统运行时间是多少? - Tim

3

最简单的版本(使用内置的awk printf - 感谢Dennis Williamson):

uptime |awk -F, '{printf "%0.f\n",$5}'

原始答案:改用xargs运行它。

uptime |awk -F, '{print $5}' |xargs printf "%0.f\n"

那么,xargs 在这里到底有什么作用呢?假设 uptime 的输出是单行的。 - Dennis Williamson
xargs将awk的输出附加到命令行的末尾。因此,如果awk的输出为0.75,则会得到'printf "%0.f\n" 0.75'。 - Will Bickford
我知道xargs的作用,但我忘记了printf不接受标准输入! - Dennis Williamson

1

你可以直接这样做

printf "%.0f\n" `uptime | awk -F, '{print $5}'`

反引号本质上是命令替换,因此无论 uptime | awk -F, '{print $5}' 的输出是什么,都将成为 printf 的参数。

第一种方法的问题在于,printf 不接受来自 stdin 的参数;如果它确实从 stdin 接受参数,那么它就可以正常工作。此外,显然没有向 printf 提供参数意味着“将零放入我的参数中”。

$ echo hello | printf "%s"

$ printf "%s" hello
hello
$ printf "%.0f"
0

1
我认为你不能将输入提供给标准输入的printf。尝试这个版本:
printf "%.0f\n" `uptime | awk -F, '{print $5}'`

糟糕...慢了9秒钟。 :) - Jeremy Bourque

1
如果您已经挂载了/proc,您可以使用/proc/loadavg:
LANG=C
read _ uptime _ </proc/loadavg
printf "%.0f\n" $uptime

上述代码仅使用了内置的 shell 命令。但是,如果您愿意,也可以使用 awk:

 awk '{printf "%.0f\n",$2}' /proc/loadavg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接