我有一个包含以下内容的文件:
37 * 60 + 55.52
34 * 60 + 51.75
36 * 60 + 2.88
36 * 60 + 14.94
36 * 60 + 18.82
36 * 60 + 8.37
37 * 60 + 48.71
36 * 60 + 34.17
37 * 60 + 42.52
37 * 60 + 51.55
35 * 60 + 34.76
34 * 60 + 18.90
33 * 60 + 49.63
34 * 60 + 37.73
36 * 60 + 4.49
我需要编写一个 shell 命令或 Bash 脚本,对于该文件中的每一行,计算方程并打印结果。例如,对于第一行,我希望看到2275.52
打印。每个结果应每行打印一次。
我已经尝试过cat math.txt | xargs -n1 expr
,但这不起作用。似乎awk
也可以做到这一点,但我不熟悉该命令的语法,所以我不知道它会是什么。
答案1
这awk
似乎可以解决问题:
while IFS= read i; do
awk "BEGIN { print ($i) }"
done < math.txt
从这里
请注意,我们使用($i)
而不是$i
避免算术表达式出现问题,例如1 > 2
(print 1 > 2
将打印1
到名为 的文件中2
,而print (1 > 2)
打印0
该算术表达式的结果)。
请注意,由于 shell 变量的扩展$i
最终被解释为代码通过awk
,这本质上是代码注入漏洞。如果您不能保证文件仅包含有效的算术表达式,您需要进行一些输入验证。例如,如果文件中有一行system("rm -rf ~")
,则可能会产生严重的后果。
答案2
这是我不确定这是最好的方法
bc < toto
取决于你想用数据做什么
francois@zaphod:~$ cat > toto
37 * 60 + 55.52
34 * 60 + 51.75
36 * 60 + 2.88
36 * 60 + 14.94
36 * 60 + 18.82
36 * 60 + 8.37
37 * 60 + 48.71
36 * 60 + 34.17
37 * 60 + 42.52
37 * 60 + 51.55
35 * 60 + 34.76
34 * 60 + 18.90
33 * 60 + 49.63
34 * 60 + 37.73
36 * 60 + 4.49
francois@zaphod:~$ while read ; do echo " $REPLY" | bc ; done < toto
2275.52
2091.75
2162.88
2174.94
2178.82
2168.37
2268.71
2194.17
2262.52
2271.55
2134.76
2058.90
2029.63
2077.73
2164.49
francois@zaphod:~$
如果没有 BC 命令,您不能使用十进制值:
francois@zaphod:~$ while read ; do echo $(( "REPLY" )) ; done < toto
-bash: 37 * 60 + 55.52: syntax error: invalid arithmetic operator (error token is ".52")
francois@zaphod:~$
答案3
如果你有 perl:
perl -ne 'print eval $_,"\n"' math.txt
(我使用这个在我的笔记本电脑上每秒获得 50000 行)。
答案4
如果您只需要结果,我会得到以下提供的答案@francois-p
为了好玩和游戏,请添加paste
和sed
:
$ paste <(sed 's/\($\)/\1\t=/g' somefile) <(bc < somefile)
37 * 60 + 55.52 = 2275.52
34 * 60 + 51.75 = 2091.75
36 * 60 + 2.88 = 2162.88
36 * 60 + 14.94 = 2174.94
36 * 60 + 18.82 = 2178.82
36 * 60 + 8.37 = 2168.37
37 * 60 + 48.71 = 2268.71
36 * 60 + 34.17 = 2194.17
37 * 60 + 42.52 = 2262.52
37 * 60 + 51.55 = 2271.55
35 * 60 + 34.76 = 2134.76
34 * 60 + 18.90 = 2058.90
33 * 60 + 49.63 = 2029.63
34 * 60 + 37.73 = 2077.73
36 * 60 + 4.49 = 2164.49