如果您想要并行完成很多事情,请考虑使用GNU 并行。有一个很棒的PDFhere https://zenodo.org/record/1146014/files/GNU_Parallel_2018.pdf?download=1解释如何使用它。具体来说,我正在使用“第 9 节 - 管道模式”回答你的问题。
我不会为您重写所有代码,只是向您展示一些想法。
让我们生成一个 16,000 行的示例文件来匹配您的:
seq 16000 > YourFile
现在让我们生成一个虚拟脚本,名为YourScript
处理您的数据,如下所示:
#!/bin/bash
lines=$(wc -l < /dev/stdin)
echo "Called to process $lines lines"
sleep 2
正如您所看到的,它只是计算在其上收到的行数stdin
并告诉您有多少个并休眠 2 秒,以便您可以看到发生了什么。使其可执行:
chmod +x YourScript
现在,您可以使用GNU 并行。首先,让GNU 并行将文件拆分为 4,000 行的块,并将一个块传递给 4 个作业中的每一个:
parallel --pipe -N4000 ./YourScript < YourFile
Called to process 4000 lines
Called to process 4000 lines
Called to process 4000 lines
Called to process 4000 lines
如果您有 4 个或更多 CPU 核心,则需要 2 秒,因为默认情况下,GNU 并行每个 CPU 核心启动一项作业。
现在尝试向每个作业传递 2,000 行,并一次运行 4 个作业:
parallel --pipe -j 4 -N2000 ./YourScript < YourFile
Called to process 2000 lines
Called to process 2000 lines
Called to process 2000 lines
Called to process 2000 lines
Called to process 2000 lines
Called to process 2000 lines
Called to process 2000 lines
Called to process 2000 lines
这将在 2 秒内运行前 4 批 2,000 行,然后在另外 2 秒内运行后 4 批 2,000 行。
希望您现在可以了解如何并行化您的脚本。Remember从中读取stdin
,不是来自文件!如果您希望脚本使用 16,000 行文件的文件名作为参数运行,或者使用该文件的一部分的文件名作为参数GNU 并行,你可以使用:
parallel --pipe -N 2000 --cat YourScript {}
然后它会写入一个 2,000 行的临时文件,调用您的脚本并随后删除该临时文件。
有用的开关GNU 并行 are:
-
parallel --dry-run ...
它告诉你它会做什么而不实际做任何事情
-
parallel --bar ...
这会给你一个进度条
-
parallel --eta ...
这会给你一个预计到达时间
另请注意GNU 并行可以在网络中的其他机器上分配工作,并且它具有失败和重试处理、输出标记等功能...
还有,你跑cut
16,000 行文件中的每一行 6 次 - 这意味着您必须分叉近 100,000 个进程!您可以使用IFS
and read
而不是这 6 个进程:
IFS='|' read -r f1 f2 f3 <<< "a|b|c"