![awk 或 perl 来评估每行中的数学表达式](https://linux22.com/image/218485/awk%20%E6%88%96%20perl%20%E6%9D%A5%E8%AF%84%E4%BC%B0%E6%AF%8F%E8%A1%8C%E4%B8%AD%E7%9A%84%E6%95%B0%E5%AD%A6%E8%A1%A8%E8%BE%BE%E5%BC%8F.png)
我想要一个脚本使 awk 成为一个交互式数学计算器,以评估每行中给出的数学表达式。
即,不要构造 awk 命令来计算如下所示的表达式:
$ awk 'BEGIN{print 180/1149}'
0.156658
$ awk 'BEGIN{print (150+141)/1149}'
0.253264
我希望我的脚本将我的数学表达式作为输入并交互式地进行计算。因此会话将如下所示(输入和输出的替代):
180/1149
0.156658
(150+141)/1149
0.253264
1 + 2
3
2 * 3 - 5
1
但是我自己无法做到这一点:
$ awk '{print}'
180/1149
180/1149
^C
$ awk '{print $0}'
180/1149
180/1149
1 + 2
1 + 2
^C
如果 awk 没有简单的解决方案,还有什么,比如 perl?
答案1
算术评估是作为awk
/perl
语言评估的一部分完成的。perl
有一个eval
在运行时将任意字符串评估为 perl 代码,所以你可以这样做:
perl -lne 'print eval $_'
但awk
事实并非如此(尽管在 GNU 的情况下awk
,它的调试器会这样做,请参见下文),因此您需要awk
为每一行输入运行,并在代码参数中传递该行的内容,例如使用 GNU xargs
:
xargs -rd '\n' -I CODE awk -- 'BEGIN{print(CODE)}'
你还可以这样做:
sed 's/.*/BEGIN{print(&)}/' | awk -f -
运行一个awk
来解释所有代码行,但awk
只会在到达输入末尾时开始对其进行评估,因此不能交互使用。不过,您可以重复使用过去评估的结果perl
。喜欢:
a = 3+4
a*2
7
那么它就会打印出来14
。
使用 gawk 的调试器
awk
有一个调试器模式,eval
您可以将 awk 代码传递给该模式进行解释,因此您可以使用以下命令劫持它:
sed -u 's/["\\]/\\&/g;s/.*/eval "print(&)"/' | gawk -D -f /dev/null
答案2
答案3
用 perl 运行它!
...或者我们也可以使用 awk。考虑以下(二阶)awk 脚本run-in-awk
#!/usr/bin/awk -f
{ system( "awk 'BEGIN{print " $0 "}' ") }
chmod +x run-in-awk
在我们实际上要求 awk 运行 awk之后
$ run-in-awk example
0.156658
0.156658
0.253264
0.253264
3
3
1
1
它还适用于标准输入键盘输入。
答案4
当我们可以将 sh 与 awk 一起使用时,为什么只使用 awk 或 perl?
#!/bin/sh
while read e_x__p_ress_ion___; do
awk "BEGIN{print ${e_x__p_ress_ion___}}"
done
这将读取一个表达式并将其保存到一个变量中。然后调用 awk print 并传递变量。这是一个在 control-c 上退出的无限循环。
这样一个奇怪的变量名是用来保护脚本不改变其他脚本的变量的。