我有大约 20 个文件,每个文件大小约为 10 GB,位于不同的文件夹中,我需要将它们压缩成一个 tar。将它们全部复制到一个位置是不切实际的。更准确地说,这些文件的组织方式如下:
index1_index2/子文件夹/bigfile.dat
这里,index1 和index2 各有几个不同的值。
获得包含所有这些文件的单个 tarball 的实用方法是什么,例如使用 bash 或其他东西?
答案1
如果它们位于同一文件系统上,您可以将它们硬链接到公共目录并 tar那目录。
或者,如果您使用 GNU tar,您可以(稍微灵活一些)将它们软链接到公共目录,并使用其-h
选项 tar 软链接指向的文件。
的手册页后者显示:
-h
,--dereference
遵循符号链接;归档并转储它们指向的文件
FreeBSD 焦油支持等效选项,但将它们命名为pax
(见下文)。
当然没有 POSIX tar 可以用来比较。如果你可以使用pax
,它有一个类似的-L
选项:
-L
如果在命令行上指定了引用类型为目录的文件的符号链接,或者在遍历文件层次结构期间遇到了符号链接,pax
则应归档以链接引用的文件为根的文件层次结构,使用链接的名称作为根文件层次结构。否则,如果pax
在命令行上指定或在遍历文件层次结构期间遇到引用通常可以归档的任何其他文件类型的文件的符号链接,pax
则应使用链接名称归档该链接引用的文件。默认行为,当两者都不是时-H
或者-L
指定的,应存档符号链接本身。
无论是硬链接还是软链接,结果都是您不必移动现有文件。硬链接变化文件的(时间戳ctime
),而软链接则不然。但是使用相同选项的 tar 实现并不普遍支持软链接(尽管它减少了位于同一文件系统上的必要性)。
OP 的原始声明似乎表明,之所以不方便将所有文件放在一个目录中,是因为生成它们的应用程序存在一些限制。澄清后可以明显看出问题在于它们都具有相同的文件名。当链接到一个目录时(例如对其原始目录进行编码)目录名到公共位置)当然是可行的,还有其他选项可以简单地将文件收集到单个存档中,并保留其现有的目录名称。这样做的一个缺点是它限制了恢复到任意位置的能力。然而:将大约 20 个名称传递给 tar 的最简单方法是在命令行上,例如,
`tar czf myoutput.tar.gz $(find . -type f -name bigfile.dat)`
对于只有 20 个文件,这不太可能是命令行长度的问题。如果它是大量文件(或非常长的路径名),这将使事情变得更加困难,因为tar
实现通常缺乏传递路径名列表的能力,而不是作为单独的命令行参数(请参阅索拉里斯例如)。对于这些,人们可能会尝试通过逐步创建存档来解决这一限制 - 但这不适用于压缩。某些实现提供了从文件读取文件名列表的选项。这GNU 焦油-T
(也是 FreeBSD)选项可以做到这一点。其他程序可能提供第三种选择,从标准输入读取文件名列表(如帕克斯,这受到了CPIO),但一般 tar 不会:它可能会读取文件内容来自标准输入。
答案2
最直接的方法是:
tar cfz bigtar.tar.gz /path/to/file1 /path/to/file2 ... /path/to/file20
如果目标文件之间存在匹配的相似性,您可以使用GNU的( )find
创建文件列表。tar
-T
--files-from
例如,如果它们都是 .mp4 文件:
find /path -type -f -iname '*.mp4' | tar cf bigtar.tar -T -
否则,如果没有简单的模式来选择文件名,您可以使用 find 在 tmpfile 中创建初始列表,手动编辑该列表以删除您不想包含在 tar 中的文件名,然后使用编辑后的 tmpfile 的名称焦油的-T
选项。