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



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

split -b 100m myImage.iso


似乎应该有一种比阅读每一行都更有效的方法使用cat将代码编码到一组文件中,然后将输出重定向到新文件。就像打开两个文件一样,从第一个文件中删除EOF标记并进行连接-无需遍历所有内容。

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

xaa
xab
xac
xad


与cat相比,在Linux上是否有类似或更好的方法来连接大文件?

更新

似乎cat实际上是连接文件的正确方法和最佳方法。很高兴知道我一直在使用正确的命令:)谢谢大家的反馈。

评论

旁注:最好不要使用cat x *,因为文件的顺序取决于您的区域设置。最好先输入cat x,而不要先按Esc再按*-您将看到文件的扩展顺序并可以重新排列。

除了考虑使用cat x *,还可以考虑使用shell括号扩展,使用cat xa {a..g}将指定的序列扩展为cat xaa xab xac xad xae xaf xag

@rozcietrzewiacz-您能否举一个例子,说明我如何调整将破坏cat x *的语言环境设置?新的语言环境设置是否也不会影响split,因此,如果在同一系统上使用split和cat x *,它们将始终有效?

“打开两个文件,从第一个文件中删除EOF标记,然后将它们连接-无需遍历所有内容。” ...听起来好像您需要发明一个新的文件系统才能执行所需的操作

@cwd:在GNU Coreutils中查看split.c,后缀是由固定的字符数组构成的:static char const * suffix_alphabet =“ abcdefghijklmnopqrstuvwxyz”;。后缀将不受语言环境的影响。 (但我认为任何理智的语言环境都不会对小写字母重新排序;即使EBCDIC仍保持其标准顺序。)

#1 楼

这就是cat的用途。因为它是最古老的GNU工具之一,所以我认为其他任何工具都不可能更快,更好地做到这一点。而且它不是管道,它只是重定向输出。

评论


猫x,然后按Esc键,您提到的很整洁。。

– Peter.O
2011-11-15 12:46

不用客气:)另外,当命令行中有该文件列表时,可以使用Ctrl + W剪切单词,然后使用Ctrl + Y粘贴单词。

–rozcietrzewiacz
2011年11月15日12:50



猫的意思是“连接”

– JoelFan
2011年11月15日16:12

..和“ catenate”源自拉丁语“ catena”,意为“一条链”。.级联是连接一条链的链接。 ...(还有一些离题的地方,悬链曲线也源自“ catena”。这是链条悬挂的方式)

– Peter.O
2011年11月15日在17:03

#2 楼

在幕后

没有比复制第一个文件,然后复制第二个文件等等更有效的方法了。 DOS copycat都这样做。

每个文件都独立于磁盘上的其他文件存储。几乎每个旨在在类似磁盘的设备上存储数据的文件系统都是由块操作的。这是发生的情况的高度简化的表示形式:磁盘分为1kB的块,操作系统为每个文件存储组成它的块的列表。大多数文件的块长度不是整数,因此最后一个块仅被部分占用。实际上,文件系统具有许多优化,例如在几个文件之间共享最后的部分块,或者存储“块46798至47913”,而不是存储“块46798,块46799……”。当操作系统需要创建一个新文件时,它将寻找可用的块。块不必是连续的:如果只有块4、5、98和178可用,则仍可以存储4kB文件。使用块而不是降低到字节级别有助于使查找新文件或正在增长的文件的可用块的速度大大提高,并减少了在创建或增长和删除或缩小许多文件时碎片造成的问题(留下越来越多的文件)。孔)。

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

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

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

关于拆分和合并

splitcat是拆分和合并文件的简单方法。 split负责产生按字母顺序命名的文件,因此cat *可以用于连接。

cat的缺点在于,对于常见的故障模式而言,它不可靠。如果其中一个文件被截断或丢失,则cat不会抱怨,您只会得到损坏的输出。它们不是很统一,因为它们除了拆分外还压缩和打包(将多个文件组合成一个文件)(相反,除了连接外还要解压缩和解压缩)。但是它们很有用,因为它们可以验证您是否拥有所有零件,并且零件是否完整。

#3 楼


似乎应该有一种比通过系统的stdin / stdout传递所有内容更有效的方法,除非那不是真的。该外壳程序将cat的stdout直接连接到打开的文件,这意味着“通过stdout”与写入磁盘相同。

评论


我只是在想象使用cat在控制台中显示几GB的代码,然后将其捕获并放入文件中。这就是我对使用cat并重定向看不到的输出时必须发生的事情的心理印象。看起来好像有一种方法可以打开两个文件,将它们连接起来,然后关闭它们,这比使用cat运行所有代码行更为有效。感谢您让我知道直接连接。

– cwd
2011年11月15日14:16



@cwd可以设计一个文件系统,在该系统中可以以这种方式连接两个文件,但这会使文件系统的设计复杂化。您需要针对一项操作进行优化,但要以使许多常见任务变得更加复杂和缓慢为代价。

–吉尔斯'所以-不再是邪恶的'
2011-11-15 23:29

@Gilles-了解有关底层细节的更多信息会很有趣。对我来说,从硬盘上读取所有扇区以获得几个文件,然后将它们转回磁盘上其他未使用的扇区,似乎效率很低。而且我认为大文件有时必须存储在多个空闲扇区块中,因为可能并不总是有足够的块并排存储它们。因此,从理论上讲,您可以通过删除EOF标记并在下一个文件的开头指向一组扇区来将文件合并为一个文件。 * nix功能强大,所以我想知道是否有比猫更好的方法。

– cwd
2011-11-15 23:53

@cwd没有“ EOF标记”。没有一个理智的现代文件系统能像这样工作,因为它可以防止某些字符出现在文件中(或者需要复杂的编码)。但是,即使在大多数情况下,即使有一个EOF标记,您也无法找到正确的文件。

–吉尔斯'所以-不再是邪恶的'
2011年11月15日23:59

我的意思是EOF标记的概念,而不是实际的EOF标记。否则,如果您查看硬盘驱动器上文件的位和字节,您如何知道文件的结尾?您是否在文件的开头指定了文件的长度?我说的是一个非常低级的东西。这就是您所说的吗?

– cwd
2011年11月16日下午0:04

#4 楼

我曾经遇到过一个确切的问题:我想加入一些文件,但是没有足够的磁盘空间来加倍保存它们。

所以我写了一堆程序: br />通过读取文件来“吸收”文件,将其发送到stdout,如果完成,则将其删除
,然后通过文件“即时”缓冲数据。使我能够执行类似的操作,从而在仍未写入128M的情况下删除源文件。有点危险,但是如果数据不是那么宝贵,或者它们也存在于其他地方,那是可行的。

如果需要,我可以提供数据源。

#5 楼

文件拆分

按大小拆分

如果要将大文件拆分为小文件并选择小输出文件的名称和大小,这就是这种方法。

split -b 500M videos\BigVideoFile.avi SmallFile.


这样,您可以选择将一个大文件拆分为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
...


按行数分割

通过这种方式,您可以将文本文件分割为50行以下的较小文件。 br />
split -l 50 text_to_split.txt


按字节分割

分割成具有自定义大小的小文件(以字节为单位)的小文件: br />结果应该类似于“按行数拆分”的结果。

文件联接

可以用两种方式联接文件。第一个是:

xaa xab xac ...


或带有:

split -b 2048 BigFile.mp4


注意:当您连接文件较小文件不应损坏。同样,所有小文件(部分)也应位于同一目录中。

#6 楼

从技术上讲,这是一种无需读取和写入整个内容即可访问整个文件的方法,对于大文件或空间不足的情况可能很有用:

$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &


,然后使用myImage.iso,例如,

$ md5sum myImage.iso


当然,myImage.iso是一个特殊文件(命名管道),而不是常规文件,因此是否使用取决于您要执行的操作。