将查找的文件列表通过管道传输到 xargs gzip 并再次通过管道传输到 Pigz

将查找的文件列表通过管道传输到 xargs gzip 并再次通过管道传输到 Pigz

我需要找到比x天更新的文件,然后将其转换为gzip,但我想使用pigz来完成。

现在我正在以缓慢的方式进行;这有效:

find /path/to/src -type f -mtime -90 | xargs tar -zcf archive.tar.gz

pigz速度要快得多,所以我想使用 Pigz 来运行这个 gzip。我尝试了这个,但它不起作用:

find /path/to/src -type f -mtime -90 | xargs tar -zcf | pigz > archive.tar.gz

它返回一个错误,因为我只是猜测要做什么(并尝试了几种方法):

tar (child): /path/to/src: Cannot open: Is a directory
tar (child): Error is not recoverable: exiting now

如何获取第一条有效的线路并将其通过管道输送到 Pigz 中?

答案1

在任何支持的 shell 上使用 GNU tar流程替代(例如 bash、ksh、zsh):

tar cf archive.tar.gz -I pigz --null -T <(find /path/to/src  -type f -mtime -90 -print0)

它用于进行压缩,并通过or选项和进程替换pigz从 的输出中获取要包含在存档中的(NUL 分隔的)文件列表。find ... -print0-T--files-from=FILE

或者,如果您使用的是仅具有 POSIX 功能的极简 shell(例如 ash 或 dash,或者 bash 作为 /bin/sh或与--posixset -o posix或与POSIXLY_CORRECT环境变量集一起运行),您可以将 NUL 分隔的文件名列表通过管道传输到 GNU tar 中。下面--T选项告诉 tar 从 stdin 读取文件列表。

find /path/to/src  -type f -mtime -90 -print0 | tar cf archive.tar.gz -I pigz --null -T -

其中任何一个都适用于任何有效的文件名,甚至包含空格、换行符和 shell 元字符的文件名。它还避免了@Kusalananda 在他的评论中提到的文件名太多的问题。

顺便说一句,您可能想使用像素代替pigz。确实如此xz压缩(通常比 gzip 压缩得更好,但速度更慢),如果 pixz 检测到类似 tar 的输入,它会添加索引以加快特定文件的提取速度。顺便说一句,两者pixzxz-utils针对最常见的 Linux 发行版进行了打包,因此应该很容易安装。

答案2

假设 GNU 或 libarchive 的tar

find /path/to/src -type f -mtime -90 -print0 |
  tar -cf - --no-recursion --null -T - |
  pigz > archive.tar.gz

--no-recursion这里并不是严格必要的,因为报告的文件find不是类型目录)。

不要使用(无论如何,如果您使用and 's ,它只能在's 输出xargs上使用),因为它最终可能会运行多个,所以您最终会得到只包含最后一批的存档。find-0find-print0tar

tar在这里,我们直接通过管道传递文件列表,-T -因此对可以通过这种方式传递的文件数量没有限制。这也意味着tar一旦找到文件就可以开始归档。

star@希利的 (RIP) tar) 还具有内置find功能:

star cf - -find /path/to/src -type f -mtime -90 |
  pigz > archive.tar.gz

不过,您也可以使用与上述其他两种语法相同的方法:

find /path/to/src -type f -mtime -90 -print0 |
  star cf - -read0 list=- |
  pigz > archive.tar.gz

tar是一个非常不可移植的命令。甚至 tar 格式s是不可携带的。X/Open/SUSv2 用于指定tar命令(和cpio),但他们最终放弃了它,因为不可能协调tar来自不同供应商的 s,而是 POSIX / SUS 提出pax作为两者的替代品。

pax从 stdin 获取文件列表,但不幸的是,换行符分隔而不是 NUL 分隔,这意味着它无法归档任意文件名,尽管某些pax实现支持-0扩展名(find's-print0也不是 POSIX,但可以替换为-exec printf '%s\0' {} +)。所以,有了这些:

find /path/to/src -type f -mtime -90 -print0 |
  pax -0w |
  pigz > archive.tar.gz

(请注意,每个 POSIX 都未定义默认输出格式,这是 的另一个弱点pax。其最大的弱点是其采用率非常低)。

相关内容