对于在 Unix 上做事相当陌生,希望制作一个脚本来按顺序执行以下操作:
- 获取主 .tsv 文件,分成 X 个文件,每个文件包含 Y 行
- 通过程序运行每个分割文件,完成后输出一个新的 .tsv 文件
- 等待所有分割文件完成处理,然后将输出文件拼接成一个。
我知道如何使用split
和sed
来分割文件,并且我无法想象让分割文件通过Python脚本运行也很困难,但问题是找出并行程序的所有执行何时完成,然后缝合它们的输出合而为一。
据split
我所知,它会自动递增名称,并且您可以对其进行大规模并行化正如这个SO问题中所见,所以我可以弄清楚那部分。有没有办法检查一组并行Python脚本的执行状态?我怎样才能完成我想做的事?
答案1
split -l $Y main.tsv main_part_
for part in main_part_*; do
program $part &
done
wait
echo "all done"
wait
是 bash 内置函数:查看手册页了解详细信息
答案2
正如吉尔斯在评论中已经指出的那样。GNU并行非常适合这项工作,因为它具有用于分割和保持分割段重新连接顺序的内置设施。通常它按行分割,但您可以为此指定特定的记录开始和结束,并命令它为所有分割作业重复标题(如果是.tsv
制表符分隔的值文件,这可能是列标题,并且更容易编写您的处理程序)。我用过这个并行执行xz
。
如果您的处理程序是一个过滤器,从标准输入获取输入并将输出写入标准输出,那么这项工作就最容易了。下面假设你的 python 程序被称为xyz
基本调用是
cat input.tsv | parallel --pipe -k xyz > output.tsv
该--pipe
选项使并行将输入解释为要分割的数据并发送到程序以调用(它有其他模式),并保持-k
输出有序。
手册部分关于--pipe
详细介绍块大小;记录开始和结束(默认情况下会复制但可以隐藏);和重复的标题。
如果您的xyz
程序需要命令行选项,您可以在输出重定向之前在命令行上指定它们 ( > ..
)
如果您有最新版本(无论如何您应该),您可以使用更有效的--pipepart
选项,假设输入是一个文件(即可查找)并且不使用记录和行计数:
parallel -a input.tsv --pipepart -k xyz > output.tsv