尝试使用 awk sqrt 但仅 returns 0

Attempted to use awk sqrt but only returns 0

我试图在我的脚本中使用 awk 命令中的 sqrt 函数,但它 returns 全部为 0。我下面的脚本有什么问题吗?

echo "enter number"
read root
awk 'BEGIN{ print sqrt($root) }'

我是第一次使用awk命令,有没有哪里不明白的地方?

也许你可以试试这个。

echo "enter number"
read root
echo "$root" | awk '{print sqrt([=10=])}'

你必须给 awk 一个数据输入。所以,你可以管道'echo'。 BEGIN语句是做一些事情,比如打印一个header...等等 awk 开始读取输入。

更新:我提出的解决方案被证明是有潜在危险的。请参阅 以获得更好的解决方案。 我会将此答案留在这里作为警告。

由于单引号,$root 由 awk 解释,而不是由 shell 解释。 awk 将 root 视为未初始化的变量,其值为空字符串,在数字上下文中被视为 0$root 是当前行的第 root 个字段——在本例中为 [=17=],即整行。因为它在 BEGIN 块中,所以没有当前行,所以 $root 是空字符串——当传递给 sqrt().[= 时,它再次被视为 0 27=]

您可以通过稍微更改命令行来查看:

$ awk 'BEGIN { print sqrt("") }'
0
$ echo 2 | awk '{ print sqrt($root) }'
1.41421

注意:以上只是为了说明原始命令有什么问题,以及 shell 和 awk 如何解释它。

一种解决方案是使用双引号而不是单引号。 shell 扩展双引号内的变量引用:

$ echo "enter number"
enter number
$ read x
2
$ awk "BEGIN { print sqrt($x) }" # DANGEROUS
1.41421

做这种事情的时候要小心。 shell 与 awk 中引用和变量扩展之间的交互可能很复杂。

更新: 事实上,您需要非常小心。正如 Ed Morton 在评论中指出的那样,如果 $x 具有恶意值,此方法可能会导致任意代码执行,这始终是从用户输入中读取值的风险。 避免了这个问题。

(请注意,我已将您的 shell 变量的名称从 $root 更改为 $x,因为它是您想要平方根的数字,而不是根本身。 )

$ echo "enter number"
enter number
$ read root
3
$ awk -v root="$root" 'BEGIN{ print sqrt(root) }'
1.73205

有关将 shell 变量的值传递给 awk 脚本的 2 种正确方法,请参见 the comp.unix.shell FAQ