Awk大于小于

Awk大于小于,awk,Awk,我正在使用这个命令 num1=2.2 num2=4.5 result=$(awk 'BEGIN{print ($num2>$num1)?1:0}') 这总是返回0。无论num2>numl还是num1>num2 但是当我把实际的数字放在这里 result=$(awk 'BEGIN{print (4.5>2.2)?1:0}') 我将得到一个返回值1。这是正确的 我能做些什么来实现这一点呢?因为bash没有扩展$num1和$num2——您使用的是单引号。不过,以下措施将起作用: re

我正在使用这个命令

num1=2.2
num2=4.5

result=$(awk 'BEGIN{print ($num2>$num1)?1:0}')
这总是返回0。无论num2>numl还是num1>num2 但是当我把实际的数字放在这里

result=$(awk 'BEGIN{print (4.5>2.2)?1:0}')
我将得到一个返回值1。这是正确的


我能做些什么来实现这一点呢?

因为bash没有扩展
$num1
$num2
——您使用的是单引号。不过,以下措施将起作用:

result=$(awk "BEGIN{print ($num2>$num1)?1:0}")
但是,请注意,正如评论中指出的,这是糟糕的编码风格,并且混合了bash和awk。就我个人而言,我并不介意这样的构想;但一般来说,特别是对于复杂的事情,如果您不记得在双引号中bash将对哪些事情进行评估,请转到这个问题的其他答案

请参见下面评论中@EdMorton的优秀示例

编辑:实际上,我会使用
bc
,而不是awk:

$num1=2.2
$num2=4.5

result=$( echo "$num2 > $num1" | bc ) 
为什么??因为它只是更清楚一点。。。而且更轻

或者使用Perl(因为它比较短,我更喜欢Perl而不是awk,因为我更喜欢backticks而不是
$()

或者,花哨一点(可能效率低下):

(是的,我知道)

在史前时期,我对awk有过短暂、密集、长达3年的接触。如今,bash无处不在,可以做很多事情(我当时只有sh/csh),所以它经常可以用来代替awk,而计算机的速度足以让Perl在临时命令行中代替awk。只要说一句就行了。

试着这样做:

result=$(awk -v num1=2.2 -v num2=4.5 'BEGIN{print (num2 > num1) ? 1 : 0}')
见:

man awk | less +/'^ *-v'

使用变量时失败的原因是,用单引号括起来的
awk
脚本是由
awk
而不是
bash
计算的:因此,如果要将使用的变量从
bash
传递到
awk
,则必须使用
-v
选项指定它,如下所示:

num1=2.2
num2=4.5

result=$(awk -v n1=$num1 -v n2=$num2 'BEGIN{print (n2>n1)?1:0}')

注意
awk
脚本中使用的程序变量不得以
$

作为前缀,这可能适用于您:

result=$(awk 'BEGIN{print ('$num2'>'$num1')?1:0}')

”想象成是通过
awk
命令向底层
bash
shell戳洞。

谢谢,我也尝试了这个表单,但是添加了$n2和$n1,这两个都不起作用。再次感谢您的另一个答案“awk shell”??awk不是shell,就像C不是shell一样。在从shell调用的C程序中,您不会期望能够访问shell变量的值,在从shell调用的awk程序中,您也不应该期望能够访问shell变量的值。谢谢,只是太多人似乎认为awk是shell,这会导致语法和变量的混淆,所以它是im区别很重要。不,绝对不要做这两件事。谷歌搜索原因。@EdMorton——你是说使用变量的代码注入?在变量被污染的环境中,可能根本不应该使用awk。与被污染的变量无关,它们可能完全有你想要的值,并且仍然可以使用警告你,再加上使用双引号版本,你必须转义脚本中的其他字符,如$s和反斜杠,它很快就会变得一团糟。最后,如果你的脚本增长到需要使用-f将其放入文件中执行的程度,你就不能来回跳转到shell。你不应该这样做。嗯,是的,像这样混合两种语言并不是编码礼仪的最高点。但是,我永远不会说从不,我认为这在这里已经足够好了。是的,我是一个Perl编码器。下面是一个简单的例子:一个设计用来打印shell变量内容的程序是
awk“BEGIN{print$shellvar}”
。在设置
shellvar=“3”
后调用它,它将按预期输出3,但在设置
shellvar=“c”
后调用它,它将打印一个空行。现在将脚本更改为
awk-v awkvar=“$shellvar””开始{print awkvar}“
它会像预期的那样分别打印3和c。不涉及受污染的变量……然后仔细考虑这对脚本的影响,然后不要这样做。请看我刚才在同一个线程中与一月的讨论。@poton这只适用于整数
num1=2.2
num2=4.5

result=$(awk -v n1=$num1 -v n2=$num2 'BEGIN{print (n2>n1)?1:0}')
result=$(awk 'BEGIN{print ('$num2'>'$num1')?1:0}')