Gzip
就地解壓gzip文件
我有一個用 gzip 壓縮的大文件(420 GB),我想解壓縮它,但我的硬碟沒有空間來儲存整個壓縮文件及其內容。
有沒有辦法在“刪除它的同時”解壓它?
如果它有幫助, gzip -l 說裡面只有一個文件(這是一個 tar 文件,我也必須以某種方式分離)
提前致謝!
有沒有辦法在“刪除它的同時”解壓它?
這就是你所要求的。但這可能不是你真正想要的。使用風險自負。
如果 420GB 文件儲存在具有稀疏文件和打孔支持的文件系統上(例如
ext4
,xfs
但不支持ntfs
),則可以使用 讀取文件並釋放讀取塊fallocate --punch-hole
。但是,如果該過程因任何原因被取消,則可能無法恢復,因為剩下的只是一個半刪除、半未壓縮的文件。不要在沒有先複製源文件的情況下嘗試它。非常粗略的概念證明:
# dd if=/dev/urandom bs=1M count=6000 | pigz --fast > urandom.img.gz 6000+0 records in 6000+0 records out 6291456000 bytes (6.3 GB, 5.9 GiB) copied, 52.2806 s, 120 MB/s # df -h urandom.img.gz Filesystem Size Used Avail Use% Mounted on tmpfs 7.9G 6.0G 2.0G 76% /dev/shm
urandom.img.gz
文件佔用76%的可用空間,所以不能直接解壓。管道未壓縮的結果,md5sum
以便我們稍後驗證:# gunzip < urandom.img.gz | md5sum bc5ed6284fd2d2161296363edaea5a6d -
打孔時解壓縮:(這非常粗糙,沒有任何錯誤檢查)
total=$(stat --format='%s' urandom.img.gz) # bytes total=$((1+$total/1024/1024)) # MiB for ((offset=0; offset < $total; offset++)) do # read block dd bs=1M skip=$offset count=1 if=urandom.img.gz 2> /dev/null # delete (punch-hole) blocks we read fallocate --punch-hole --offset="$offset"MiB --length=1MiB urandom.img.gz done | gunzip > urandom.img
結果:
# ls -alh * -rw-r--r-- 1 root root 5.9G Jan 31 15:14 urandom.img -rw-r--r-- 1 root root 5.9G Jan 31 15:14 urandom.img.gz # du -hcs * 5.9G urandom.img 0 urandom.img.gz 5.9G total # md5sum urandom.img bc5ed6284fd2d2161296363edaea5a6d urandom.img
校驗和匹配,源文件的大小從 6GB 減少到 0,而它在原地未壓縮。
但是有很多事情可能會出錯……最好根本不要這樣做,或者如果你真的必須這樣做,至少使用一個可以進行更明智的錯誤檢查的程序。上面的循環根本不保證數據在被刪除之前已被讀取和處理。如果
dd
或gunzip
由於任何原因返回錯誤,fallocate
仍然很樂意將其扔掉……所以如果你必須使用這種方法,最好編寫一個更理智的read-and-eat
程序。