捕获多个文件的最快方法是什么?

时间:2010-11-01 19:25:04

标签: unix concatenation cat

我想知道是否有办法更快地将unix文本文件连接在一起 而不是运行cat

这是我面临的问题。我正在处理一个文本文件~100G in 尺寸。我试图通过将文件分成数百个来改进运行时 较小的文件并行处理它们。最后我抓住了结果 文件按顺序一起返回。文件读/写时间本身需要数小时。一世 我想找到一种改进方法:

cat file1 file2 file3 ... fileN >> newBigFile
  1. 这要求磁盘空间加倍file1 ... fileN占用100G, 然后newBigFile需要另外100Gb,然后file1 ... fileN获得 除去

  2. 数据已在file1 ... fileN,执行cat >>会导致读取 当我真正需要的是数百个文件时,写出时间 重新出现为1个文件......

8 个答案:

答案 0 :(得分:8)

如果您不需要随机访问最终的大文件(即,您只需从头到尾阅读一次),您就可以将数百个中间文件显示为一个。你通常会去哪里

$ consume big-file.txt

代替

$ consume <(cat file1 file2 ... fileN)

这使用Unix process substitution,有时也称为“匿名命名管道”。

您也可以通过拆分输入并同时进行处理来节省时间和空间; GNU Parallel有一个--pipe switch就可以做到这一点。它还可以将输出重新组合成一个大文件,可能使用较少的临时空间,因为它只需要一次将核心数块保留在磁盘上。如果您实际上同时运行数百个进程,则Parallel会通过调整计算机的并行度来大大提高效率。我强烈推荐它。

答案 1 :(得分:5)

也许dd会更快,因为你不必在cat和shell之间传递东西。类似的东西:

mv file1 newBigFile
dd if=file2 of=newBigFile seek=$(stat -c %s newBigFile)

答案 2 :(得分:4)

你有可能根本不拆分文件吗?而是通过在每个并行工作程序中设置文件指针来处理文件。如果文件需要以面向行的方式处理,这会使它变得更加棘手但仍然可以完成。每个工作人员都需要理解,而不是从你给它的偏移量开始,它必须首先逐字节地搜索到下一个换行符+1。每个工作者还必须了解它不会处理您给出的设定字节数,但必须在分配给处理的设定字节数后处理第一个换行符。

文件指针的实际分配和设置非常简单。如果有n个worker,则每个都处理n /文件大小字节,文件指针从worker号* n / file_size开始。

有什么理由认为这种计划还不够吗?

答案 3 :(得分:4)

将文件重新连接在一起时,您可以删除附加的小文件:

for file in file1 file2 file3 ... fileN; do
  cat "$file" >> bigFile && rm "$file"
done

这样可以避免需要两倍的空间。

没有其他方法可以神奇地使文件神奇地连接起来。文件系统API根本就没有这样做的功能。

答案 4 :(得分:3)

快速但不是免费的解决方案?获取SSD驱动器或基于闪存PCIe的存储。如果这是必须定期完成的事情,那么提高磁盘IO速度将是您可以获得的最具成本效益和最快速的速度。

答案 5 :(得分:3)

我相信这是捕获同一文件夹中包含的所有文件的最快方法:

$ ls [path to folder] | while read p; do cat $p; done

答案 6 :(得分:2)

我真正需要的是将数百个文件重新显示为1个文件...

在文件系统级别加入文件是不切实际的,因为文本文件通常不会完全填充磁盘块,因此后续文件中的数据必须向上移动以填补空白,导致一堆读/写无论如何

答案 7 :(得分:2)

存在太多并发性。

更好的方法是在所需范围内对文件使用随机访问读取,并且实际上不会将其拆分并仅处理文件数量作为计算机中物理CPU /核心的数量。除非用IOPS淹没磁盘,否则你应该减少直到磁盘不是瓶颈。

无论采用哪种方式进行所有天真的分割/复制/删除,你所做的就是产生大量的IOPS,并且无法解决它的物理问题。

一个透明的解决方案,除了这是一个持续的日常问题/问题之外,可能是比值得更多的工作,是编写一个自定义的FUSE文件系统,将单个文件表示为多个文件。有很多关于将存档文件内容作为单个文件处理的示例,它们将向您展示如何执行此操作的基础知识。