我将值存储在变量 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- 使用
var1
inawk
(不需要$
,$var1
var1=6 就是$6
的值) (忘记 awk 中的 BEGIN )echo
提供输入awk
(否则 awk 将挂起等待输入)
答案2
$var1
在这里,您可以传递和的内容$var2
壳变量作为awk
脚本的参数,并通过特殊的数组变量在脚本中访问它们ARGV
:
var=$(awk -- 'BEGIN {printf "%.2f", ARGV[1] / ARGV[2]}' "$var1" "$var")
或者您可以将var1
和var2
shell 变量导出到环境用于通过其数组变量awk
检索它们:ENVIRON
var=$(
export var1 var2
awk 'BEGIN {printf "%.2f", ENVIRON["var1"] / ENVIRON["var2"]}'
)
在一般情况下,通常最好使用ARGV
/ ENVIRON
over-v
或var=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
,这对于这样一个简单的脚本来说是有问题的,但对于更复杂的脚本来说是有意义的,这里有两种方法可以解决这个问题:
只需用双引号替换简单引号即可。简单的方法可以阻止美元扩张。这引入了其他问题,例如需要对现有双引号进行转义,以及如果您想在
awk
) 中使用字段,则需要相同的要求。var=`awk "BEGIN {printf \"%.2f\n\", $var1/ $var2}"`
将变量传递给
awk
正确的方式:var=$(awk -v var1="$var1" var2="$var2" 'BEGIN {printf("%`.2f\n",var1,var2)}')