使用 awk 除以零异常

使用 awk 除以零异常

我将值存储在变量 var1=6 和 var2=4 中,我尝试将它们以精度 2 相除并将结果存储在变量中var

var=`awk 'BEGIN {printf "%.2f\n", $var1/ $var2}'`

当我执行上述操作时我得到 awk: cmd. line:1: fatal: division by zero attempted

有人可以指出我在这里到底缺少什么吗?

谢谢!

答案1

用于-v var=value将变量传递给 awk。

因此

awk -v var1="$var1" -v var2="$var2" 'BEGIN {printf "%.2f\n",var1/var2}'

1.50

var=$(awk -v var1="$var1" -v var2="$var2" 'BEGIN {printf "%.2f\n",var1/var2}') 

设定值。

你需要

  • -v var1="$var1"将 bash 的 $var1 转换为 awk 的 var1
  • 使用var1in awk(不需要$$var1var1=6 就是$6的值)
  • echo提供输入awk(否则 awk 将挂起等待输入)(忘记 awk 中的 BEGIN )

答案2

$var1在这里,您可以传递和的内容$var2 变量作为awk脚本的参数,并通过特殊的数组变量在脚本中访问它们ARGV

var=$(awk -- 'BEGIN {printf "%.2f", ARGV[1] / ARGV[2]}' "$var1" "$var")

或者您可以将var1var2shell 变量导出到环境用于通过其数组变量awk检索它们:ENVIRON

var=$(
  export var1 var2
  awk 'BEGIN {printf "%.2f", ENVIRON["var1"] / ENVIRON["var2"]}'
)

在一般情况下,通常最好使用ARGV/ ENVIRONover-vvar=value参数来传递任意数据,因为后者会破坏反斜杠字符(尽管对于数字来说这并不是真正的问题)。

应避免在 的代码参数中嵌入 shell 变量的扩展,awk因为这相当于代码注入漏洞。同样适用于忘记在参数中引用参数扩展-v

请注意,如果 shell 是ksh93或,则此处根本zsh不需要:awk

printf -v var %.2f '1.*var1 / var2' # zsh
var=${ printf %.2f '1.*var1 / var2'; } # ksh93

(其中与 的乘法强制1.计算以浮点形式完成)。

但请注意,您需要清理这些变量的内容,否则这将是另一个任意代码执行漏洞如果这些变量的内容不在您的控制之下。

答案3

如果您确实想使用awk,这对于这样一个简单的脚本来说是有问题的,但对于更复杂的脚本来说是有意义的,这里有两种方法可以解决这个问题:

  1. 只需用双引号替换简单引号即可。简单的方法可以阻止美元扩张。这引入了其他问题,例如需要对现有双引号进行转义,以及如果您想在awk) 中使用字段,则需要相同的要求。

    var=`awk "BEGIN {printf \"%.2f\n\", $var1/ $var2}"`
    
  2. 将变量传递给awk正确的方式:

    var=$(awk -v var1="$var1" var2="$var2" 'BEGIN {printf("%`.2f\n",var1,var2)}')
    

相关内容