fdm*_*ion 1 pipe shell-script xz
假设我有四个非常大的文本文件,都用 xz 压缩。
file1.log.xz
file2.log.xz
file3.log.xz
file4.log.xz
Run Code Online (Sandbox Code Playgroud)
我想做的是将这四个文件的未压缩内容连接成一个新文件file.xz。问题是,我希望不必通过中间文件。
这些文件是非常大的日志文件,大小为千兆字节。压缩后,它们小于 100MB,但如果我要扩展所有四个文件然后重新连接,我至少需要 30GB 的存储空间来存储未压缩的文件。当然,我可以将cat所有未压缩的文件xz重新压缩:
cat file1.log file2.log file3.log file4.log | xz -ve9 - > newfile.log.xz
Run Code Online (Sandbox Code Playgroud)
我知道如何在没有中间件的情况下在命令行中连接两个文件,假设一个未压缩,一个已压缩:
xz -d -c file2.log.xz | cat file1.log - | xz -ve9 - > files1and2.log.xz
Run Code Online (Sandbox Code Playgroud)
但这仅适用于一个文件,其中之一必须已经解压缩。
我不确定我是否可以cat将各种 .xz 文件放在一起 - 让我们假设它们可能已经用不同的参数进行了压缩。
在更高的层次上,可以问这个问题本身:您能否获取多个(超过两个)命令的输出,连接这些输出,并将它们通过管道传输到另一个进程而无需中间文件?(假设场景:假设我正在使用输出到 stdout 的脚本对所有四个非常大的文件进行某种处理,并希望将输出放入另一个压缩文件中。)
是否可以仅使用 shell 命令来执行此操作?
该xz文件说,
可以按
.xz原样连接文件。xz将解压缩这些文件,就好像它们是单个.xz文件一样。
从我的测试来看,即使使用不同的选项压缩不同的文件,这也有效;所以在你的情况下
cat -- *.log.xz > newfile.log.xz
Run Code Online (Sandbox Code Playgroud)
会正常工作。
要回答更一般的问题,您可以通过管道传输复合命令的输出,例如
for file in -- *.log.xz; do xzcat -- "$file"; done | xz -ve9 > newfile.log.xz
Run Code Online (Sandbox Code Playgroud)
或任何子外壳。这将允许您在重新压缩日志文件之前对其进行任何处理。但是,在基本情况下,这也不是必需的;您可以通过运行来解压缩和重新压缩所有文件
xzcat -- *.log.xz | xz -ve9 > newfile.log.xz
Run Code Online (Sandbox Code Playgroud)
如果您添加-f它甚至适用于未压缩的文件,那么
xzcat -f -- uncompressed.log *.log.xz | xz -ve9 > newfile.log.xz
Run Code Online (Sandbox Code Playgroud)
将允许您组合未压缩和压缩的日志。