我需要将一堆文件合并到具有 8 个核心的 unix 机器上的目录中。我正在寻找一种快速合并这些文件的方法。 cat 命令仅使用一个核心...有没有一种方法可以让它使用多个核心进行并行处理。
答案1
没有有效的方法来并行化追加 I/O 操作;每行必须依次写下来。
答案2
首先,确认性能瓶颈。如果磁盘 io 是你的瓶颈,多线程就没用了。
如果您有一个非常快的磁盘或 SSD,您可以统计文件的长度、计算偏移量并使用多个 dd 命令。
答案3
像这样的脚本怎么样(用 sleep 来演示它如何并行化操作):
#!/bin/bash
eval exec 3\<<(echo FIRST FILE; sleep 3)
eval exec 4\<<(echo SECOND FILE; sleep 3)
cat <&3
cat <&4
它并行读取输入文件。请注意,这在很多方面都受到限制,并且不会并行化输出,但无论如何这是无法完成的。
这是一个更完整的示例,它处理当前目录中的所有文件:
#!/bin/bash
fd=3
for file in *
do
eval exec $fd\<<(cat $file)
fd=$((fd + 1))
done
out_fd=3
while [ "$out_fd" -lt "$fd" ]
do
cat <&${out_fd}
out_fd=$((out_fd + 1))
done
上面关于性能的几点都很好;这可能根本没有帮助。
更新 进一步思考,这只会预取管道缓冲区大小 64k。以下修改会将所有文件拉入内存;如果它们不适合,请不要使用它:
#!/bin/bash
fd=3
for file in *
do
eval exec $fd\<<(content=$(<$file); echo "$content")
fd=$((fd + 1))
done
out_fd=3
while [ "$out_fd" -lt "$fd" ]
do
cat <&${out_fd}
out_fd=$((out_fd + 1))
done