![如何就地压缩文件?](https://linux22.com/image/64068/%E5%A6%82%E4%BD%95%E5%B0%B1%E5%9C%B0%E5%8E%8B%E7%BC%A9%E6%96%87%E4%BB%B6%EF%BC%9F.png)
我有一台硬盘使用率为 90% 的机器。我想将其 500 多个日志文件压缩为一个较小的新文件。然而,硬盘太小,无法同时保存原始文件和压缩文件。
所以我需要的是将所有日志文件逐个压缩到一个新文件中,并在压缩后删除每个原始文件。
我怎样才能在 Linux 中做到这一点?
答案1
我自己想出了一个 tar 解决方案。
它将单个文件压缩到目标文件后删除。
不过,压缩速度不是很快。该命令如下所示:
tar -zcvf my_log.tar.gz *.log --remove-files
答案2
gzip
或者bzip2
将压缩文件并自动删除未压缩的文件(这是它们的默认行为)。
但是,请记住,在压缩过程中,两个文件都将存在。
如果您想压缩日志文件(即:包含文本的文件),您可能更喜欢bzip2
,因为它对于文本文件具有更好的比率。
bzip2 -9 myfile # will produce myfile.bz2
比较与示例:
$ ls -l myfile
-rw-rw-r-- 1 apaul apaul 585999 29 april 10:09 myfile
$ bzip2 -9 myfile
$ ls -l myfile*
-rw-rw-r-- 1 apaul apaul 115780 29 april 10:09 myfile.bz2
$ bunzip2 myfile.bz2
$ gzip -9 myfile
$ ls -l myfile*
-rw-rw-r-- 1 apaul apaul 146234 29 april 10:09 myfile.gz
更新正如 @Jjoao 在评论中告诉我的,有趣的是,xz
似乎在普通文件及其默认选项上有一个最佳比例:
$ xz -9 myfile
$ ls -l myfile*
-rw-rw-r-- 1 apaul apaul 109384 29 april 10:09 myfile.xz
有关更多信息,这里是不同工具的有趣基准:http://binfalse.de/2011/04/04/comparison-of-compression/
对于上面的示例,我使用-9
最佳压缩比,但如果压缩数据所需的时间比压缩比更重要,则最好不要使用它(使用较低的选项,即-1
,或介于两者之间的选项)。
答案3
当您在 bash 中使用 io 重定向时>
,在写入新数据之前原始文件将为空。
有一个命令 dd 可以覆盖文件的某些内容,而不是在写入之前清空文件,因此以下命令可能有效:
gzip -c some-file | dd conv=notrunc of=some-file
大多数情况下,压缩数据比原始数据小。当gzip读取前N个字节时,它只输出M个字节,其中M < N,因此可以安全地用压缩数据覆盖原始文件的前M个字节,并保留前N个字节后的数据不变。
但gzip结束后会有数据。
但是,如果 dd 写入速度比 gzip 快,我不知道会发生什么。
或者你可以通过losetup将文件映射到块设备。对于块设备,写操作不会清空原始数据。
loop_device=$(losetup -f--show some-file)
gzip -c $loop_device > $loop_device
答案4
我试图在 BSD 版本的 tar 上执行此操作。在这种情况下,--remove-files 选项不可用。我最终做的(和工作的)是:
find folder_to_tar -type f -exec tar --append --file=output_tar_file.tar {} \; -exec rm -v {} \;