在BASH中将浮点变量输出为十进制文件

时间:2014-11-24 20:41:13

标签: bash shell

BASH时间(运行5次)的结果以十进制形式存储在文本文件中。 然后我读回数值并使用bc计算平均值。 最后,我将得到的平均值作为小数输出到文件中。 我的脚本似乎有效,(Linux Mint上的Mate Terminal没有错误, 除了文件的最终输出为“0”外,都创建了.txt文件。

TIMEFORMAT=%R
tsum=0

for i in {1..5}
do
(time sh -c \
'openssl des3 -e -nosalt -k 0123456789012345 -in orig.jpg -out encr.enc; '\
'openssl des3 -d -nosalt -k 0123456789012345 -in encr.enc -out decr.dec'\
) 2>&1 | grep 0 >> outtime.txt
done

avgDES3=0
cat outtime.txt | \
while read num
do
tsum=`echo $tsum + $num | bc -l`
done

avgDES3=`echo "$tsum / 5" | bc -l`
echo "DES3 average is: " $avgDES3 >> results.txt

我也尝试用以下代码替换最后一行:     printf“DESCBC平均值是:”$ avgDESCBC>> RESULTS.TXT

outtime.txt是:

0.220
0.218
0.226
0.223
0.217

和results.txt是:

DES3 average is:  0

我很感激帮助将结果平均值设为小数。也许我没有在最后一行使用tsum变量的正确值(例如,如果tsum全局没有被循环中的表达式改变)?

编辑:问题(正如rbong和Arun所指出的)是一个子管道(全局变量在循环表达式后没有改变)。 Origninally脚本在我的系统上生成了适当的outtime.txt(没有错误,只是没有从循环中得到tsum值)。

2 个答案:

答案 0 :(得分:1)

使用bash -x选项执行脚本进行调试,发现tsum变量在while循环中按预期运行,然后在循环退出后将其值重置为零。

这是因为您在|之前使用while运算符时创建了一个新的子进程,并且子进程有自己的变量副本。您可以通过不将cat的输出传递给循环来避免这种情况,而是使用重定向运算符来实现相同的结果而不创建子进程。

这是通过更改此

来完成的
cat outtime.txt | \
while read num
do
tsum=`echo $tsum + $num | bc -l`
done

到这个

while read num
do
    tsum=`echo $tsum + $num | bc -l`
done < outtime.txt

通过这个简单的更改,您的新输出变为

DES3 average is:  .22080000000000000000

要了解更多信息,请阅读此处。

http://www.gnu.org/software/bash/manual/html_node/Redirections.html

答案 1 :(得分:0)

试试这个脚本。使用{,} time time命令可以捕获&#34; time&#34;的输出。命令和使用&#34; 2&#34;用于在追加模式下创建outtime.txt文件的标识符。在开始编写脚本之前,应该新建这个文件,或者你可以评论&#34;&gt; outtime.txt&#34;线。 A&#39 ;;&#39;关闭之前的角色&#39;}&#39;支撑是重要的,或者它不会结束开始&#39; {&#39;。这将 FIX 你的outtime.txt文件内容/数据问题。

其他问题在于使用while循环&#34; |&#34;在while循环之前,由于为while循环创建了一个新的子shell,而tsum变量在while循环之外失去了它的值。循环播放&#34; outtime.txt&#34;文件如下图所示。

#!/bin/bash

TIMEFORMAT=%R
tsum=0

#create fresh outtime.txt and results.txt files
>outtime.txt

#if you want this file to be appended for future runs, comment the following line.
>results.txt

for i in {1..5}
do
{ time sh -c \
'openssl des3 -e -nosalt -k 0123456789012345 -in orig.jpg -out encr.enc; '\
'openssl des3 -d -nosalt -k 0123456789012345 -in encr.enc -out decr.dec'\
} 1>/dev/null 2>&1; } 2>> outtime.txt
done
## Now at this point, outtime.txt will contain only x.xxx time entries per line for 5 runs of "for" loop.
echo File outtime.txt looks like:
echo ----------
cat outtime.txt
echo;
## Now lets calculate average.
avgDES3=0
while read num
do
tsum=`echo $tsum + $num | bc -l`
done < outtime.txt; ## Feed while loop this outtime.txt file


avgDES3=`echo "$tsum / 5" | bc -l`
echo "DES3 average is: " $avgDES3 > results.txt
## Logically you should usr a single > re-director for results file. Instead of >> which is used for appending to file while creating results.txt.

#Show the output/average
echo; echo File results.txt looks like:
cat results.txt

<强>输出:

File outtime.txt looks like:
----------
0.112
0.108
0.095
0.084
0.110


File results.txt looks like:
DES3 average is:  .10180000000000000000