如何在Linux上就地压缩文件而不使用额外的磁盘空间?


20

我有一个具有95GB文件的100GB驱动器。我需要释放驱动器上的一些空间(现在无法从驱动器上传输文件)。使用gzipbz2其他方式,该文件都可以很好地压缩,但是所有这些程序都将压缩后的文件写入单独的文件。我没有足够的可用空间。

有没有一种方法可以使用标准压缩工具或其他Unix实用程序来压缩文件,而无需使用任何额外的磁盘空间(或至少最少数量的额外磁盘空间)?我正在想象一次压缩文件一部分并将结果直接写在文件上的东西。我意识到这样做是有风险的,因为如果压缩被中断,文件将被破坏,但我认为我没有选择。


我们以前在过去的地方使用的最后一个选择是在某个目录中放置一个目录,其中包含一堆充满垃圾的1G文件。然后,如果您遇到困难,可以将其中的一些移开,以留出一些应急空间。

Answers:


13

这是bash一线概念证明,但它应该可以帮助您入门。使用风险自负。

truncate -s `gzip -c file | dd of=file conv=notrunc 2>&1 | sed -n '$ s/ .*$// p'` file
mv file file.gz

这是通过将gz数据传递到dd进程并将其写回到同一文件中而起作用的。完成后,文件将被截断为gz输出的大小。

假设dd的输出的最后一行匹配:

复制了4307字节(4.3 kB),2.5855e-05 s,167 MB / s

其中第一个字段是写入的字节整数。这是文件将需要被截断的大小。我不确定100%的输出格式是否始终相同。


漂亮的把戏。您能解释为什么conv=notrunc有必要吗?
sleske 2012年

也许不是。gzip -c file | dd of=file似乎同样有效。
user710307 2012年

1
遇到相关问题的人都尝试过(我也尝试过);它一般不起作用。似乎它仅适用于很小的文件-可能是因为gzip在压缩之前会将一个小文件读入RAM。对于大文件(几个MB),即使它们是可压缩的,它也不起作用。
sleske 2012年

3
是的 因此conv = notrunc是必需的。
user710307 2012年

1
压缩程序(例如gzip)是否有可能比原始数据字节写入更多的标头和数据字节,从而覆盖了文件的某些部分?我猜这取决于所选的压缩程序。有谁知道如何防止这种情况的发生或这种可能性的大小?
DanielBöhmer16年

7

这不是这么多,gzipbzip2覆盖原来的。相反,他们将压缩数据作为一个新文件写入磁盘,并且如果该操作成功,他们将取消链接原始的未压缩文件。

如果有足够的RAM,则可以编写脚本来临时压缩文件tmpfs系统中的文件,然后删除磁盘上的原始文件并将其替换为压缩版本。也许是这样的:

# some distributions mount /dev/shm as tmpfs; replace with bzip2 if you prefer
if gzip -q9c /full/disk/somefile > /dev/shm/somefile.gz
then
    rm -f /full/disk/somefile && mv -i /dev/shm/somefile.gz /full/disk
fi

请注意您的内存使用情况,因为tmpfs本质上是RAM磁盘。较大的输出文件很容易使系统饿死,并给您带来其他问题。


1
那简直太疯狂了,无法工作
Andrew Lambert 2012年

我喜欢推信封。
James Sneeringer 2012年

3

正是出于您给出的原因,没有任何一种工具可以这样工作。很少有人愿意编写故意实施危险行为的工具。


我希望它对实用程序来说是不安全的,非默认的选项。你能想到一个替代方案吗?有没有办法将文件截断到适当的位置,例如删除前2 GB?这样一来,我就可以使用有限的可用空间来一次压缩一个块,并在执行过程中缩小源文件。

实际上,没有任何方法可以使用任何工具从任何文件系统上的文件开头删除数据。
伊格纳西奥·巴斯克斯

2
但是您可以从文件末尾删除数据。原则上可以做到。您将数据从文件末尾切下来以放入单独的文件中,并在操作时截断原始文件。然后,您按向前的顺序压缩文件,然后将其删除。实施起来会很痛苦,如果出现任何问题,您将被搞砸。但这是可能的。
David Schwartz

1

split和csplit命令可用于将大文件拆分为较小的部分,然后单独压缩它们。但是,重新组装将非常耗时。


另一个不错的选择。一个人可能可以编写一些脚本来做到这一点。但是,这会产生许多单独压缩的文件,在解压缩后需要重新连接它们,这不是很好。
sleske 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.