我想知道是否有办法更快地将unix文本文件连接在一起
而不是运行cat
?
这是我面临的问题。我正在处理一个文本文件~100G in 尺寸。我试图通过将文件分成数百个来改进运行时 较小的文件并行处理它们。最后我抓住了结果 文件按顺序一起返回。文件读/写时间本身需要数小时。一世 我想找到一种改进方法:
cat file1 file2 file3 ... fileN >> newBigFile
这要求磁盘空间加倍file1
... fileN
占用100G,
然后newBigFile
需要另外100Gb,然后file1
... fileN
获得
除去
数据已在file1
... fileN
,执行cat >>
会导致读取
当我真正需要的是数百个文件时,写出时间
重新出现为1个文件......
答案 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文件系统,将单个文件表示为多个文件。有很多关于将存档文件内容作为单个文件处理的示例,它们将向您展示如何执行此操作的基础知识。