自动执行需要使用数千个不同参数运行的命令

时间:2012-07-13 02:06:42

标签: mysql ruby-on-rails shell automation large-files

在我的项目中,我需要将一个大文件(~250GB)上传到远程服务器,然后运行脚本将文件加载到mysql中。 问题是,如果我加载单个文件,则需要很长时间。因此,我必须将文件拆分为小型中继,并在多个终端中同时运行10-20个进程。如果我将每个文件分成~2MB,那么我需要运行100,000次。然后我必须像

那样运行
ruby importer.rb data_part01_aa.csv
ruby importer.rb data_part01_ab.csv
ruby importer.rb data_part01_ac.csv
.
.
.

在每个终端中,等待它们结束,然后运行下一个终端。

是否有任何方法可以自动执行此过程?任何shell脚本可以在前一个完成后继续完成工作吗? 非常感谢!

1 个答案:

答案 0 :(得分:0)

在shell中你可以尝试:

for i in *.csv
do
    ruby importer.rb $i.csv
done

前一个可以写成一行如下:

for i in *.csv; do ruby importer.rb data_part01_aa.csv; done

最终,如果参数太多,可能需要一些时间才能开始运行。在这种情况下,您可以尝试使用find

find . -name '*.csv' -exec ruby importer.rb {} \;

但是,上一个命令将在每个子目录中递归搜索。要使其仅针对当前目录运行,您必须运行:

find . -maxdepth 1 -name '*.csv' -exec ruby importer.rb {} \;

在给出的每个示例中,命令将按顺序运行。而不是*.csv您可以使用不同的模式(例如a*.csvb*.csv[ab]*.*csv等),或者您可以尝试其他循环:

for j in $(echo {a..q})
do
    find . -name "data_part01_$j?.csv" -exec ruby importer.rb {} \; &
done

其中echo {a..q}生成从 a q 的字母序列,它似乎跟随您的文件名称。最后一个示例中的关键是& ,它将进程留在后台,在最后一个示例中,将同时运行17个进程。如果你不想同时使用它们,那么你只需要删除&符号&