如果我有一个大文件并且需要将其拆分为 100 MB 的块,我会这样做
split -b 100m myImage.iso
这通常会给我类似的东西
xaa
xab
xac
xad
为了让它们重新组合在一起,我一直在使用
cat x* > myImage.iso
似乎应该有一种比读取一组文件中的每一行代码并将cat
输出重定向到新文件更有效的方法。就像打开两个文件、EOF
从第一个文件中删除标记并连接它们一样 - 无需浏览所有内容。
Windows/DOS 有一个用于二进制文件的复制命令。帮助提到该命令旨在能够合并多个文件。它使用以下语法:(/b
适用于二进制模式)
copy /b file1 + file2 + file3 outputfile
在 Linux 上是否有比 cat 类似或更好的方法来连接大文件?
更新
看起来这cat
实际上是连接文件的正确方法和最佳方法。很高兴知道我一直在使用正确的命令:)感谢大家的反馈。
答案1
就是这样cat
是为.由于它是最古老的 GNU 工具之一,我认为任何其他工具不太可能做得更快/更好。这不是管道- 它只是重定向输出。
答案2
在引擎盖下
没有比复制第一个文件,然后复制其后的第二个文件,依此类推更有效的方法了。 DOS 都copy
可以cat
这样做。
每个文件都独立于磁盘上的其他文件存储。几乎每个设计用于在类似磁盘的设备上存储数据的文件系统都按块进行操作。下面是对所发生情况的高度简化的演示:磁盘被划分为 1kB 大小的块,操作系统为每个文件存储组成该文件的块的列表。大多数文件的块长度都不是整数,因此最后一个块仅被部分占用。实际上,文件系统有很多优化,例如在多个文件之间共享最后一个部分块或存储“块46798到47913”而不是“块46798、块46799……”。当操作系统需要创建新文件时,它会查找空闲块。这些块不必是连续的:如果只有块 4、5、98 和 178 空闲,您仍然可以存储 4kB 文件。使用块而不是深入到字节级别有助于更快地为新文件或不断增长的文件查找可用块,并减少创建或增长以及删除或收缩大量文件时由于碎片而产生的问题(留下越来越多的文件)孔)。
您可以支持文件中间的部分块,但这会增加相当大的复杂性,特别是在非顺序访问文件时:要跳转到第 10340 个字节,您不能再跳转到第 11 个块的第 100 个字节,您必须检查每个中间块的长度。
考虑到块的使用,您不能只连接两个文件,因为通常第一个文件在块中间结束。当然,您可能会遇到特殊情况,但前提是您想在连接时删除两个文件。对于罕见的操作来说,这将是高度具体的处理。这种特殊处理本身并不存在,因为在典型的文件系统上,许多文件正在同时被访问。因此,如果您想添加优化,您需要仔细考虑:如果其他进程正在读取所涉及的文件之一,会发生什么情况?如果有人在连接 A 和 C 时尝试连接 A 和 B,会发生什么?等等。总而言之,这种罕见的优化将是一个巨大的负担。
总而言之,如果不在其他地方做出重大牺牲,就无法提高文件连接的效率。这不值得。
关于分裂和合并
split
和cat
是分割和合并文件的简单方法。split
负责生成按字母顺序命名的文件,以便cat *
适用于连接。
for join的一个缺点cat
是它对常见故障模式的鲁棒性不强。如果其中一个文件被截断或丢失,cat
您不会抱怨,您只会得到损坏的输出。
有一些压缩实用程序可以生成多部分存档,例如zipsplit
和rar -v
。它们不是很统一,因为除了分割之外,它们还压缩和打包(将多个文件组装成一个文件)(相反,除了连接之外,还进行解包和解压缩)。但它们很有用,因为它们可以验证您是否拥有所有部件,并且部件是否完整。
答案3
似乎应该有一种比通过系统
stdin
/管道传输所有内容更有效的方法stdout
但事实并非如此。 shell 正在连接的标准输出cat
直接地到打开的文件,这意味着“通过stdout”与写入磁盘相同。
答案4
我曾经遇到过这个问题:我想加入一些文件,但没有足够的磁盘空间来容纳它们。
于是我写了一堆程序:
- 一种是通过读取文件来“吸收”文件,将其发送到标准输出,如果完成,则将其删除
- 一个用于“动态”缓冲数据。
这使我能够做类似的事情
partto sourcefile | mybuffer 128M >>cumufile
从而在 128M 尚未写入的情况下删除源文件。有点危险,但如果数据不是那么珍贵,或者它们也存在于其他地方,这是可行的。
如果需要的话我可以提供源码。