变量运算符,用于awk中的数值比较

时间:2019-01-29 22:16:52

标签: awk

awk可以使用变量运算符进行数值比较吗?以下代码适用于硬编码运算符,但不适用于变量运算符:

awk -v o="$operator" -v c="$comparison" '$1 o c'

3 个答案:

答案 0 :(得分:3)

不,那是行不通的。 Awk的-v选项定义实际的Awk变量,而不是令牌级宏替换。

由于无法正常运行的原因而无法正常运行:

awk 'BEGIN { o = "+"; print 2 o 2 }'  # hoping for 2 + 2

Awk与POSIX Shell和类似语言不同;它不会通过文本替换来评估变量。

由于您是从Shell命令行调用Awk的,因此可以使用Shell的替换生成Awk语法,从而获得这种效果:

awk -v c="$comparison" "\$1 $operator c"

我们现在需要在$1上加一个反斜杠,因为我们切换到了双引号,其中$1现在被外壳本身识别了。

答案 1 :(得分:0)

Kaz提出的另一种方法是定义自己的映射函数,该函数将两个变量作为参数以及相应的运算符字符串o

awk -v o="$operator" -v c="$comparison" '
      function operator(arg1, arg2, op) {
          if (op == "==") return arg1 == arg2
          if (op == "!=") return arg1 != arg2
          if (op == "<") return arg1 < arg2 
          if (op == ">") return arg1 > arg2
          if (op == "<=") return arg1 <= arg2 
          if (op == ">=") return arg1 >= arg2 
      }
    { print operator($1,c,o) }'

这样,您还可以定义自己的运算符。

答案 2 :(得分:0)

否,但是您有两个选择,最简单的方法是在awk运行之前让shell扩展变量之一以使其成为awk脚本的一部分:

$ operator='>'; comparison='3'
$ echo 5 | awk -v c="$comparison" '$1 '"$operator"' c'
5

否则,您可以编写自己的eval样式的函数,例如:

$ cat tst.awk
cmp($1,o,c)

function cmp(x,y,z,      cmd,line,ret) {
    cmd = "awk \047BEGIN{print (" x " " y " " z ")}\047"
    if ( (cmd | getline line) > 0 ) {
        ret = line
    }
    close(cmd)
    return ret
}

$ echo 5 | awk -v c="$comparison" -v o="$operator" -f tst.awk
5

请参见https://stackoverflow.com/a/54161251/1745001。即使您的awk程序保存在文件中,后者也可以,而前者则不能。如果要将函数库与命令行脚本混合使用,那么这是使用-i的GNU awk的一种方法:

$ cat tst.awk
function cmp(x,y,z,      cmd,line,ret) {
    cmd = "awk \047BEGIN{print (" x " " y " " z ")}\047"
    if ( (cmd | getline line) > 0 ) {
        ret = line
    }
    close(cmd)
    return ret
}

$ awk -v c="$comparison" -v o="$operator" -i tst.awk 'cmp($1,o,c)'
5