对于这个HackerRank bash挑战(四舍五入到小数点后3位),以下解决方案效果很好:
$ echo '5+50*3/20 + (19*2)/7' | bc -l | awk '{ printf ("%.3f n",$1) }'
17.929
而在 printf 的格式字符串和 $1 之间没有逗号的情况下,在 bash 提示符下会产生以下错误:
$ echo '5+50*3/20 + (19*2)/7' | bc -l | awk '{ printf ("%.3f n" $1) }'
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: not enough arguments to satisfy format string
`%.3f
17.92857142857142857142'
^ ran out for this one
错误消息表明不带逗号的 $1 没有作为 printf 的参数提供,但它的省略迄今为止没有给我带来问题(awk '{ print $0 " with appendix." }'
愉快地打印附加的文本)。可以理解的是,在手册中搜索以逗号分隔的值是没有帮助的。逗号在awk中分隔参数的功能是什么(除了在字符串之间插入空格)?另外:示例中的圆括号有什么作用?对于它的价值,HackerRank给出了以下错误:
bc -l | awk '{ printf ("%.3f n" $1) }'
Your Output (stdout)
0.000
17.92857142857142857142
首先,您甚至不需要awk
将十进制数限制为小数点后 3 位。bc
本身可以做到这一点:
bc -l <<< 'scale=3; 5+50*3/20 + (19*2)/7'
17.928
现在关于printf
的问题,printf
的语法应该是:
printf format, item1, item2, …
但是当你像这样使用它时:
printf ("%.3f n" $1)
您没有提供足够数量的参数来满足%.3f
格式字符串(因为"%.3f n"
和$1
被连接成一个字符串),因此您会收到此错误:
not enough arguments to satisfy format string
即使你把括号放在周围,也不会使错误消失。(...)
在printf
中是可选的,因此它可以是以下 2 个语句之一:
printf "%.3f n", $1
printf ("%.3f n", $1)
awk 没有显式字符串连接运算符。两个字符串通过简单地并排放置来连接
print "foo" "bar" # => prints "foobar"
当你省略逗号时,你基本上是这样的:
fmt = "%.3f n" $1 # the string => "%.3fn17.92"
printf (fmt)
并且有一个 %f 指令,但没有给出值。
错误消息表明不带逗号的 $1 没有作为 printf 的参数提供,但它的省略迄今为止没有给我带来问题(
awk '{ print $0 " with appendix." }'
愉快地打印附加的文本)
是的。 这两种效果都源于这样一个事实,即awk
在没有任何显式运算符的情况下连接相邻的字符串。 不仅是字面意思。 有关详细信息和示例,请参阅手册的第 6.2.2 节。 在print
语句的情况下,这会产生符合您目的的效果,但在printf
调用的情况下,这意味着您只将一个串联参数传递给printf
,它将其解释为格式字符串。
在字符串之间放置逗号时,无论是在print
语句中还是在printf
调用中,您都会获得两个项目的列表,而不是单个串联字符串。