背景
我在一家研究风暴潮的研究机构工作,我正在尝试使用 Bash 自动化一些 HPC 命令。目前,该过程是我们从 NOAA 下载数据并逐行手动创建命令文件,输入每个文件的位置以及程序从该文件读取数据的时间和风放大系数。NOAA 生成的每个下载文件中都有数百个这样的数据文件,当暴风雨进行时,这些文件每 6 小时左右出现一次。这意味着我们在风暴期间的大部分时间都花在制作这些命令文件上。
问题
我可以用来自动执行此过程的工具有限,因为我只有一个用户帐户和每月在超级计算机上分配的时间;我无权在它们上安装新软件。另外,其中一些是 Cray,一些是 IBM,一些是 HP,等等。它们之间没有一致的操作系统;唯一的相似之处是它们都是基于 Unix 的。所以我可以使用 Bash、Perl、awk 和 Python 等工具,但不一定有 csh、ksh、zsh、bc 等工具:
$ bc
-bash: bc: command not found
此外,我的首席科学家要求我为他编写的所有代码都在 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 来循环遍历数据文件比为目录中的每个文件调用一次要快一百倍,而且这些语言可以轻松打开文件并写入文件,但问题是我我正在来回获取数据。我已经找到了很多关于这三种语言(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
...
}'
但我不确定这是正确的语法,如果是,它是否是解决此问题的最佳方法,或者它是否会起作用。几天来,我一直在撞墙,并决定在插上电源之前先上网。