评估在awk中作为参数传递的算术表达式

时间:2010-11-27 16:18:32

标签: awk

如何评估在awk中作为参数传递的算术表达式?

我在文件中有这个。

1*2*3
1+2*3
传入此文件时,

awk应输出6,7。

5 个答案:

答案 0 :(得分:3)

awk(1)是错误的工具,因为它没有eval()功能。我建议将文件修改为bc(1)的输入或使用shell算术扩展:

while read expr; do
    echo "$(($expr))"
done < file

答案 1 :(得分:1)

  1. awk没有eval()函数
  2. 使用bc或shell算术扩展都可以使它
  3. 但是,如果您在hadoop脚本中使用它,请考虑子进程问题
  4. 此外,您可以尝试以下方式:

    1. 考虑在AWK中写expression evaluatorfrom archive.org,搜索 calc3
    2. 使用eval
    3. 使用Python的eval函数

答案 2 :(得分:1)

我知道这很糟糕但我们可以:

awk '{system(sprintf("awk \"BEGIN {print " $0 "}\""))}'

正如所指出的,bc,Python eval,bash $(( ))是更好的解决方案

最后一个建议Perl:

perl -nE 'say eval'

答案 3 :(得分:0)

这是另一种受@JJoao's answer启发的 hack ,以及来自@DracoMetallium of Twitter的反馈...

#!/usr/bin/env bash


calc() {
  awk 'BEGIN { print '"${@//inf/(2 ** 1024)}"'; }'
}


calc '1/2'
#> 0.5

...这还可以处理inf的实例,这些实例是通过Bash内置的搜索和替换传递的,例如...

calc 'inf + inf'
#> inf


calc '-inf + -inf'
#> -inf


calc '-inf + inf'
#> -nan

在一个人的.bashrc文件中,这可能对基于命令行的快速计算有用。


为了完整起见,下面是一个示例,说明如何在(主要)纯Awk中执行上述操作...

calc.awk

#!/usr/bin/awk -f


function calc(expression) {
  gsub("inf", "(2 ** 1024)", expression)
  system(sprintf("awk \"BEGIN {printf(" expression ")}\""))
}


{
  print calc($0)
}

...以及用法示例...

calc.awk <<<'1 /2'
#> 0.5


printf '2*2\nsqrt(9)\n' | calc.awk
#> 4
#> 3


calc.awk <<'EOF'
22 / 7
(1 + sqrt(5)) / 2
EOF
#> 3.14286
#> 1.61803


tee -a 'input-file.txt' 1>'/dev/null' <<'EOF'
1*2*3
1+2*3
EOF


calc.awk input-file.txt
#> 6
#> 7

答案 4 :(得分:-1)

举个例子,考虑一下iftop给你的东西:

Host name                   last 2s   last 10s   last 40s cumulative

   1 10.150.1.1      =>     650B      533B        533B     2.08KB
     85.239.108.20   <=     16.0KB    12.9KB     12.9KB   51.5KB

假设您需要将2条上/下行分成一行,并将KB / B计算为正确的字节值(* 1024)。你可以这样:

iftop -i eth1 -ts 10 -Bn|egrep "<|>"| sed 's/^   //g;s/^[1-9]/x/g;s/KB/ 1024/g;s/B/ 1/g' | tr -d '\n'|tr "x" '\n'| grep .| awk '{print $1" "$11" - "$9*$10+$19*$20" "$9*$10" "$19*$20 }'