来自字符串的 awk 算术运算

awk arithmetic operation from string

我在文件中有一个特定的列,其中包含如下字符串:

1.1*1024
1.0*1024
1.1*1024
...

我想要数字结果:

1126.4
1024.0
1126.4

所以我尝试了这个,请注意尺寸在我的文件的第 6 列:

$ cat file | awk '{col=;size=sprintf("%f", col);print "=> col = "col" size = "size}'
=> col = 1.1*1024 size = 1.100000
=> col = 1.0*1024 size = 1.000000
=> col = 1.1*1024 size = 1.100000

EDIT1 我的输入文件如下所示:

$ cat file 
[[  ]]  toto1.mp4  2019-04-16  22:11  1.1*1024
[[  ]]  toto2.mp4  2019-04-16  21:41  1.0*1024
[[  ]]  toto3.mp4  2019-04-16  22:40  1.1*1024
[[  ]]  toto4.mp4  2019-04-16  22:09  1.1*1024
...

不知何故忽略了乘法。

你能帮忙吗?

这是评估字符串的通用方法,它可以处理 *+-/ 等。如果可以使用 perl 然后有 eval 字符串的选项,这将从输入中计算数学运算的字符串。

CASE-1: 评估整行时:

cat inputfile
1+1
2*2
3/3
4.5*2
5/2

perl -nle ' print eval ' inputfile
2
4
1
9
2.5

CASE-2: 仅评估一列时:在本例中为第 6 列。提供要评估的列号,F[5] 是第 6 列。

perl -nale  'print  eval  $F[5]' inputfile
1126.4
1024
1126.4
1126.4

case-3: 评估第 6 列时,但打印整个记录。评估第 6 列并更新其值,稍后打印整行。

perl -nale  '$F[5] = eval  $F[5] ;print "@F"' inputfile
[[ ]] toto1.mp4 2019-04-16 22:11 1126.4
[[ ]] toto2.mp4 2019-04-16 21:41 1024
[[ ]] toto3.mp4 2019-04-16 22:40 1126.4
[[ ]] toto4.mp4 2019-04-16 22:09 1126.4

能否请您尝试以下(仅在查看提供的示例后测试和编写)。

awk '{split($NF,array,"*");printf("%.01f\n",array[1]*array[2])}' Input_file

sprintf 无法评估操作本身。您需要对它们进行解析和评估,然后 sprintf 可用于将结果转换为特定格式的字符串。

$ awk -v OFS='  ' 'split($NF,a,/\*/)>1{$NF=a[1]*a[2]} 1' file
[[  ]]  toto1.mp4  2019-04-16  22:11  1126.4
[[  ]]  toto2.mp4  2019-04-16  21:41  1024
[[  ]]  toto3.mp4  2019-04-16  22:40  1126.4
[[  ]]  toto4.mp4  2019-04-16  22:09  1126.4

A​​wk 无法计算变量中的表达式,您需要为其构建一个计算器或以其他方式计算,例如:

$ awk '{
    cmd="awk BEGIN{print "  "}"  # prepare an external awk command 
    cmd | getline retval                 # execute
    print retval                         # output evaluated value
    close(cmd)                           
}' file

输出:

1126.4
1024
1126.4
1126.4

周围有可以计算的 awk 程序,例如 calc3。 Google是你的朋友,我的朋友。

这是你想要做的吗?

$ awk -F'[[:space:]*]+' '{printf "%.1f\n", $(NF-1) * $NF}' file
1126.4
1024.0
1126.4
1126.4

if d 文件中的数据,在 gnu awk 上试过:

 awk -F'\*' '{a=*; printf "%-6.1f\n",a}' d