拆分文件后再次加入文件的最佳方法是什么?

cwd*_*cwd 99 linux command-line iso split files

如果我有一个大文件并且需要将其拆分为 100 兆字节的块,我会这样做

split -b 100m myImage.iso
Run Code Online (Sandbox Code Playgroud)

这通常会给我类似的东西

xaa
xab
xac
xad
Run Code Online (Sandbox Code Playgroud)

为了让它们重新组合在一起,我一直在使用

cat x* > myImage.iso
Run Code Online (Sandbox Code Playgroud)

似乎应该有一种比读取一组文件中的每一行代码cat并将输出重定向到新文件更有效的方法。就像只打开两个文件、EOF从第一个文件中删除标记并将它们连接起来一样 - 无需浏览所有内容。

Windows/DOS 有一个用于二进制文件的复制命令。帮助中提到此命令旨在能够组合多个文件。它使用以下语法:(/b用于二进制模式)

copy /b file1 + file2 + file3 outputfile
Run Code Online (Sandbox Code Playgroud)

在 Linux 上是否有类似或更好的方法来加入大文件而不是 cat?

更新

看来这cat实际上是加入文件的正确方式和最佳方式。很高兴知道我一直在使用正确的命令 :) 感谢大家的反馈。

roz*_*acz 63

这正是cat为此而生的。由于它是最古老的 GNU 工具之一,我认为任何其他工具都不太可能更快/更好地做到这一点。它不是管道- 它只是重定向输出。

  • .. 和“catenate”源自拉丁语“catena”,意思是“一条链”。...(还有一点离题,*悬链线曲线*也源自“catena”。这是链条悬挂的方式) (4认同)
  • 不客气:) 另外,当您在命令行上有该文件列表时,您可以使用`Ctrl+W` 剪切一个单词,然后使用`Ctrl+Y` 粘贴它。 (2认同)

Gil*_*il' 21

引擎盖下

没有比复制第一个文件,然后复制第二个文件,依此类推更有效的方法了。DOScopy和cat这样做。

每个文件都独立于磁盘上的其他文件存储。几乎所有旨在将数据存储在类似磁盘的设备上的文件系统都按块运行。下面是对发生的事情的高度简化的演示:磁盘被分成块,比如 1kB,对于每个文件,操作系统存储组成它的块列表。大多数文件的长度不是整数个块,因此最后一个块仅被部分占用。在实践中,文件系统有很多优化,比如在几个文件之间共享最后一个部分块或存储“块 46798 到 47913”而不是“块 46798,块 46799,……”。当操作系统需要创建一个新文件时,它会寻找空闲块。块不必是连续的:如果只有块 4、5、98 和 178 空闲,您仍然可以存储 4kB 文件。

您可以在中间文件中支持部分块,但这会增加相当大的复杂性,尤其是在非顺序访问文件时:要跳转到第 10340 个字节,您不能再跳转到第 11 个块的第 100 个字节,您将有检查每个中间块的长度。

鉴于块的使用,您不能只连接两个文件,因为通常第一个文件以中间块结束。当然,您可以有一个特殊情况,但前提是您想在连接时删除两个文件。对于罕见的操作,这将是一种高度具体的处理。这种特殊处理不会单独存在,因为在典型的文件系统上,许多文件同时被访问。因此,如果要添加优化,则需要仔细考虑:如果其他进程正在读取所涉及的文件之一,会发生什么情况?如果有人在连接 A 和 C 时尝试连接 A 和 B,会发生什么?等等。总而言之,这种罕见的优化将是一个巨大的负担。

总而言之,如果不在其他地方做出重大牺牲,您就无法提高加入文件的效率。这不值得。

关于拆分和加入

split并且cat是拆分和合并文件的简单方法。split负责生成按字母顺序命名的文件,以便cat *加入。

cat加入的缺点是它对常见的故障模式不稳健。如果其中一个文件被截断或丢失,cat不会抱怨,您只会得到损坏的输出。

有一些压缩实用程序可以生成多部分存档,例如zipsplit和rar -v。它们不是很 unixy,因为除了拆分之外,它们还压缩和打包(将多个文件组合成一个)(相反,除了加入之外,还可以解压缩和解压缩)。但它们很有用,因为它们可以验证您是否拥有所有部件,并且部件是否完整。


Ign*_*ams 9

似乎应该有一种比通过系统的stdin/管道传输所有内容更有效的方法stdout

除了这不是真正发生的事情。shell 将 stdoutcat 直接连接到打开的文件,这意味着“通过 stdout”与写入磁盘相同。


Nol*_*ole 6

文件分割

按尺寸划分

如果您想将大文件拆分为小文件并选择小输出文件的名称和大小,就是这样。

split -b 500M videos\BigVideoFile.avi SmallFile.
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以选择将一个大文件拆分为 500 MB 的较小部分。您还希望零件文件的名称为 SmallFile。请注意,文件名后需要点。结果应该是生成如下新文件:

SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...
Run Code Online (Sandbox Code Playgroud)

按行数分割

这样您就可以将文本文件分割成不超过 50 行的较小文件。

split -l 50 text_to_split.txt
Run Code Online (Sandbox Code Playgroud)

结果应该是这样的:

xaa xab xac ...
Run Code Online (Sandbox Code Playgroud)

按字节分割

拆分为小文件,自定义小文件大小(以字节为单位):

split -b 2048 BigFile.mp4
Run Code Online (Sandbox Code Playgroud)

结果应该类似于Spliting By Number Of Lines的结果。

文件连接

您可以通过两种方式加入文件。第一个是:

cat SmallFile.* > OutputBigVideoFile.avi
Run Code Online (Sandbox Code Playgroud)

或与:

cat SmallFile.?? > OutputBigVideoFile.avi
Run Code Online (Sandbox Code Playgroud)

注意:当您加入文件时,小文件不应被损坏。此外,所有小(部分)文件应该位于同一目录中。