背景
我在一家研究计算风暴潮的研究机构工作,试图使用Bash自动化一些HPC命令。目前的流程是,我们从NOAA下载数据并手动创建命令文件,逐行输入每个文件的位置以及程序从该文件读取数据的时间和风扩大系数。每次NOAA发布新的风暴进展情况时,每个下载中都会有数百个这些数据文件。这意味着我们在风暴期间花费了大量时间来制作这些命令文件。
问题
由于我只有一个用户帐户和每月限定的超级计算机使用时间,所以我使用自动化工具的选择受到了限制;我没有权限在这些计算机上安装新软件。此外,其中一些计算机是Cray,一些是IBM,一些是HP等等。它们之间没有一致的操作系统,唯一相似之处就是它们都是基于Unix的。因此,我可以使用Bash、Perl、awk和Python等工具,但不一定有csh、ksh、zsh、bc等工具:
$ bc
-bash: bc: command not found
此外,我的首席科学家要求我为他编写的所有代码都是Bash语言,因为他理解它,并且尽可能少地调用无法使用Bash完成的外部程序。例如,Bash不能执行浮点数算术运算,而我需要能够添加浮点数。我可以在Bash中调用Perl,但速度较慢。
$ time perl -E 'printf("%.2f", 360.00 + 0.25)'
360.25
real 0m0.052s
user 0m0.015s
sys 0m0.015s
1/20秒似乎不算长的时间,但当我需要在一个单一文件中进行100次调用时,这相当于处理一个文件约需要5秒钟。如果我们每6个小时才制作一个这样的文件,则并不太糟糕。但是,如果将这项工作抽象成更大的任务,例如一次向大西洋盆地指定1,000场合成风暴,以研究如果风暴更强或采取不同的路径会发生什么,那么5秒钟很快就会增长到一个多小时,仅用于处理文本文件。当您按小时计费时,这就成为一个问题。
问题:有什么好方法可以加速吗?我目前在脚本中使用了这个“for”循环(需要5秒钟才能运行):
for FORECAST in $DIRNAME; do
echo $HOURCOUNT" "$WINDMAG" "${FORECAST##*/} >> $FILENAME;
HOURCOUNT=$(echo "$HOURCOUNT $INCREMENT" | awk '{printf "%.2f", $1 + $2}');
done
我知道用awk或Perl单个调用循环遍历数据文件比为目录中的每个文件分别调用这两种语言的速度快100倍以上,而且这些语言可以轻松地打开文件并写入其中,但我遇到的问题是如何在它们之间传递数据。我找到了很多关于这三种语言的资源(awk、Perl、Python),但是在将它们嵌入Bash脚本方面,我还没有找到太多信息。最接近的方法就是制作一个awk命令的外壳:
awk -v HOURCOUNT="$HOURCOUNT" -v INCREMENT="$INCREMENT" -v WINDMAG="$WINDMAG" -v DIRNAME="$DIRNAME" -v FILENAME="$FILENAME" 'BEGIN{ for (FORECAST in DIRNAME) do
...
}'
但我并不确定这是否是正确的语法,即使是正确的语法,也不知道这是否是最好的方法,或者是否会起作用。我已经撞了几天头,决定在继续之前先问问互联网。
perl -E 'printf("%.2f", 360.00 + 0.25)'
这样的东西的bash脚本更容易理解。 - David K