在 AWK 中使用 IF 语句

pet*_*uis 0 linux bash awk variable

我正在编写大脚本,我一直在坚持这一部分,如果有人可以帮助我,请

这是文件示例

31:49.9,9.92,TCP ,1_19,490,EXT_SERVER,22,5,257,1,.ASF,0,normal
Run Code Online (Sandbox Code Playgroud)

这是我脚本的一部分

read -p "Please input the function itself ex, > : " function
read -p "Please input the value: " value
Run Code Online (Sandbox Code Playgroud)

如果我像这样使用,对我来说很好用

cat temp | awk -F',' -v val="$value" '{if($8 > val) print $0}' > $destfile
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这样使用时

cat temp | awk -F',' -v val="$value" -v fn="$function" '{if($8 fn val) print $0}' > $destfile
Run Code Online (Sandbox Code Playgroud)

谢谢

ilk*_*chu 7

没有多少编程语言允许在运行时根据变量的内容生成运算符。解析代码时,if 语句条件中的表达式必须在语法上有效,但不是。$number variable variable

(当然在 shell 和test/[你可以做 eg [ "$a" "$op" "$b" ],但那是因为[是一个命令,并在 shell 扩展变量后解析它的参数。)

你有一些选择。

您可以让 shell 在 awk 解析代码之前扩展运算符,如下所示:

cat temp | awk -F',' -v val="$value" '
               {if($8 '"$function"' val) print $0}' > $destfile
Run Code Online (Sandbox Code Playgroud)

那么如果$function包含 eg <,awk 会看到{if($8 < val) .... 如果你这样做,你应该$function在运行 awk 之前验证它是一个可接受的运算符。否则您的用户可能会遇到令人惊讶的语法错误,或者更糟。


作为另一种选择,您可以让用户同时输入下限和上限,并始终在代码中检查两者。如果用户不想分别输入下限/上限,则替换例如-inf/+inf或其他一些足够低/高的值。

read -p "Please enter lower limit: " lo
read -p "Please enter upper limit: " hi
cat temp | awk -F',' -v lo="${lo:--inf}" -v hi="${hi:-+inf}" '
               {if (lo <= $8 && $8 <= hi) print $0}' > $destfile
Run Code Online (Sandbox Code Playgroud)

-inf/+inf似乎直接在 GNU awk 和 Busybox 中工作,mawk 似乎需要强制它们使用数字lo + 0 <= $8等)


我想在 GNU awk 中,第三种选择是为您想要提供的所有不同比较运算符创建函数,然后根据变量中给出的名称使用间接函数调用来调用其中一个。

例如对于小于和大于测试:

read -p "Please input the function (lt or gt): " op
read -p "Please input the value: " value
cat temp | gawk -F',' -v op="$op" -v val="$value" '
                function lt(a, b) { return a < b; }
                function gt(a, b) { return a > b; }
                {if (@op($8, val)) print $0}'
Run Code Online (Sandbox Code Playgroud)

这样做的缺点当然是您必须显式创建所有函数,如果用户输入无效的函数名称,则会出现错误。