如何檢查兩個 gzip 壓縮文件是否相等?
我試圖通過簡單地將數據轉儲到文本文件中來節省空間,同時進行“啞”備份。我的備份腳本每天執行一次,如下所示:
- 創建一個以備份日期命名的目錄。
- 將一些數據轉儲到文本文件
"$name"
中。- 如果文件是有效的,gzip 它:
gzip "$name"
. 否則,rm "$name"
。現在,如果前一天也有相同的數據可用,我想添加一個額外的步驟來刪除文件(並創建符號連結或硬連結)。
起初我想使用
md5sum "$name"
,但這不起作用,因為我還儲存了文件名和創建日期。是否
gzip
可以選擇比較兩個 gzip 壓縮文件並告訴我它們是否相等?如果gzip
沒有這樣的選擇,還有其他方法可以實現我的目標嗎?
@derobert的回答很棒,儘管我想分享一些我發現的其他資訊。
gzip -l -v
gzip 壓縮文件已經包含一個雜湊(雖然不安全,請參閱此 SO 文章):
$ echo something > foo $ gzip foo $ gzip -v -l foo.gz method crc date time compressed uncompressed ratio uncompressed_name defla 18b1f736 Feb 8 22:34 34 10 -20.0% foo
可以結合 CRC 和未壓縮的大小來獲得快速指紋:
gzip -v -l foo.gz | awk '{print $2, $7}'
CMP
要檢查兩個字節是否相等,請使用
cmp file1 file2
. 現在,一個 gzip 壓縮文件有一些帶有數據和頁腳(CRC 加上原始大小)的標題。gzip 格式的描述顯示,標頭包含文件壓縮的時間,並且文件名是一個以 nul 結尾的字元串,附加在 10 字節標頭之後。因此,假設文件名是常量並且使用相同的命令( ),可以通過使用並跳過包括時間在內的第一個字節
gzip "$name"
來檢查兩個文件是否不同:cmp
cmp -i 8 file1 file2
注意:假設相同的壓縮選項很重要,否則該命令將始終將文件報告為不同。發生這種情況是因為壓縮選項儲存在標頭中,並且可能會影響壓縮數據。
cmp
只查看原始字節,不要將其解釋為 gzip。如果您有相同長度的文件名,那麼您可以嘗試計算讀取文件名後要跳過的字節數。當文件名大小不同時,您可以
cmp
在跳過字節後執行,例如cmp <(cut -b9- file1) <(cut -b10- file2)
.zcmp
這絕對是最好的方法,它首先壓縮數據並開始比較字節
cmp
(真的,這是在zcmp
(zdiff
) shellscript 中所做的)。一個註釋,不要害怕手冊頁中的以下註釋:
如果在比較之前必須解壓縮兩個文件,則將第二個文件解壓縮到 /tmp。在所有其他情況下,zdiff 和 zcmp 僅使用管道。
當您擁有足夠新的 Bash 時,壓縮不會使用臨時文件,而只是使用管道。或者,正如
zdiff
消息來源所說:# Reject Solaris 8's buggy /bin/bash 2.03.