我想要一个脚本使 awk 成为一个交互式数学计算器,以评估每行中给出的数学表达式。
即,不要构造 awk 命令来计算如下所示的表达式:
$ awk 'BEGIN{print 180/1149}'
0.156658
$ awk 'BEGIN{print (150+141)/1149}'
0.253264
Run Code Online (Sandbox Code Playgroud)
我希望我的脚本将我的数学表达式作为输入并交互式地进行计算。因此会话将如下所示(输入和输出的替代):
180/1149
0.156658
(150+141)/1149
0.253264
1 + 2
3
2 * 3 - 5
1
Run Code Online (Sandbox Code Playgroud)
但是我自己无法做到这一点:
$ awk '{print}'
180/1149
180/1149
^C
$ awk '{print $0}'
180/1149
180/1149
1 + 2
1 + 2
^C
Run Code Online (Sandbox Code Playgroud)
如果 awk 没有简单的解决方案,还有什么,比如 perl?
算术评估是作为awk/perl语言评估的一部分完成的。perl有一个eval在运行时将任意字符串评估为 perl 代码,所以你可以这样做:
perl -lne 'print eval $_'
Run Code Online (Sandbox Code Playgroud)
但事实awk并非如此(尽管在 GNU 的情况下awk,它的调试器会这样做,请参见下文),因此您需要awk为每一行输入运行,并在代码参数中传递该行的内容,例如使用 GNU xargs:
xargs -rd '\n' -I CODE awk -- 'BEGIN{print(CODE)}'
Run Code Online (Sandbox Code Playgroud)
你还可以这样做:
sed 's/.*/BEGIN{print(&)}/' | awk -f -
Run Code Online (Sandbox Code Playgroud)
运行一个awk来解释所有代码行,但awk只会在到达输入末尾时开始对其进行评估,因此不能交互使用。不过,您可以重复使用过去评估的结果perl。喜欢:
a = 3+4
a*2
Run Code Online (Sandbox Code Playgroud)
7那么它就会打印出来14。
awk有一个调试器模式,eval您可以将 awk 代码传递给该模式进行解释,因此您可以使用以下命令劫持它:
sed -u 's/["\\]/\\&/g;s/.*/eval "print(&)"/' | gawk -D -f /dev/null
Run Code Online (Sandbox Code Playgroud)
交互方式,只需使用bc
非交互式地,如果您想编写表达式计算的脚本:
$ cat file
180/1149
(150+141)/1149
1 + 2
2 * 3 - 5
$ bc < file
.15665796344647519582
.25326370757180156657
3
1
Run Code Online (Sandbox Code Playgroud)
为了交错输入和输出,我们可以使用paste
$ paste -d '\n' file <(bc < file)
180/1149
.15665796344647519582
(150+141)/1149
.25326370757180156657
1 + 2
3
2 * 3 - 5
1
Run Code Online (Sandbox Code Playgroud)