Eu estou tentando economizar espaço ao fazer um backup "burro" simplesmente despejando dados em um arquivo de texto. Meu script de backup é executado diariamente e fica assim:
- Crie um diretório com o nome da data do backup.
- Despejar alguns dados em um arquivo de texto
"$name"
. - Se o arquivo for válido, gzip-lo:
gzip "$name"
. Caso contráriorm "$name"
,.
Agora, quero adicionar uma etapa adicional para remover um arquivo se os mesmos dados também estiverem disponíveis no dia anterior (e criar link simbólico ou link físico).
No começo, pensei em usar md5sum "$name"
, mas isso não funciona, porque também armazeno o nome do arquivo e a data de criação.
Tem gzip
uma opção para comparar dois arquivos compactados em gzip e me dizer se são iguais ou não? Se gzip
não houver essa opção, existe outra maneira de alcançar meu objetivo?
gzip
file-comparison
Lekensteyn
fonte
fonte
diff <(zcat file1) <(zcat file2)
, mas a sugestão de mrethubzdiff
parece muito melhor.Respostas:
Você pode usar
zcmp
ouzdiff
como o mreithub sugere em seu comentário (ou no comando de Kevin, que é semelhante). Eles serão relativamente ineficientes, pois na verdade descompactam os dois arquivos e os passam paracmp
oudiff
. Se você quer apenas responder "eles são iguais", você quercmp
, será muito mais rápido.Sua abordagem com o
md5sum
é perfeitamente boa, mas você precisa usar o MD5 antes de executargzip
. Em seguida, armazene-o em um arquivo ao lado do.gz
arquivo resultante . Você pode comparar o arquivo facilmente, antes de compactá-lo. Se o nome for o mesmo,md5sum -c
fará isso por você.E o próximo backup:
Então não mudou. OTOH, ele mudou:
Se você passar
--quiet
para ele, ele fornecerá o código de saída. 0 para correspondência, não 0 para diferença.O MD5 é bastante rápido, mas não de forma flagrante. O MD4 (
openssl md4
é o melhor que você obtém na linha de comando, acredito) é duas vezes mais rápido (nem o MD5 é seguro, mas ambos são tão resistentes a colisões quando ninguém tenta subvertê-los). SHA-1 (sha1sum
) é mais seguro, mas mais lento; O SHA-256 (sha256sum
) é seguro, mas ainda mais lento. O CRC32 deve ser muitas vezes mais rápido, mas é mais curto e, portanto, terá mais colisões aleatórias. Também é totalmente inseguro.fonte
zdiff
parece um desperdício, pois eu só quero saber se um arquivo foi alterado, não o que .zcmp
parece interessante, vou tentar isso.A resposta de @derobert é ótima, embora eu queira compartilhar outras informações que encontrei.
gzip -l -v
Os arquivos compactados com gzip já contêm um hash (embora não seja seguro, veja este post no SO ):
Pode-se combinar o CRC e o tamanho não compactado para obter uma impressão digital rápida:
cmp
Para verificar se dois bytes são iguais ou não, use
cmp file1 file2
. Agora, um arquivo compactado com gzip tem algum cabeçalho com os dados e o rodapé (CRC mais o tamanho original) anexados. A descrição do formato gzip mostra que o cabeçalho contém a hora em que o arquivo foi compactado e que o nome do arquivo é uma sequência terminada em nulo que é anexada após o cabeçalho de 10 bytes.Portanto, assumindo que o nome do arquivo seja constante e o mesmo comando (
gzip "$name"
) seja usado, é possível verificar se dois arquivos são diferentes usandocmp
e pulando os primeiros bytes, incluindo o horário:Nota : supondo que as mesmas opções de compactação sejam importantes, caso contrário, o comando sempre reportará o arquivo como diferente. Isso acontece porque as opções de compactação são armazenadas no cabeçalho e podem afetar os dados compactados.
cmp
apenas analisa os bytes brutos e não os interpreta como gzip.Se você tiver nomes de arquivos do mesmo tamanho, tente calcular os bytes a serem ignorados depois de ler o nome do arquivo. Quando os nomes de arquivos tiverem tamanhos diferentes, você poderá executar
cmp
depois de pular bytes, comocmp <(cut -b9- file1) <(cut -b10- file2)
.zcmp
Este é definitivamente o melhor caminho a seguir, ele primeiro comprime os dados e começa a comparar os bytes com
cmp
(realmente, é isso que é feito no shellscriptzcmp
(zdiff
)).Uma nota, não tenha medo da seguinte nota na página de manual:
Quando você tem um Bash suficientemente novo, a compactação não usa um arquivo temporário, apenas um canal. Ou, como a
zdiff
fonte diz:fonte
gzip -v -l
que relatará o tempo do arquivo em vez de MTIME se os quatro bytes MTIME no cabeçalho forem zero. Observe também que se MTIME estiver lá, normalmente é um pouco antes do horário do arquivo, porque é quando a compactação é iniciada.Para comparar dois arquivos gzip, apenas o conteúdo, um comando, não
diff
, apenas comparandomd5sum
Você também pode "filtrar" as diferenças relevantes,
Se estiver usando scripts, recomendo uma função de filtro (não testada, apenas um exemplo),
fonte
cmp
.zcat
egrep
pode ser mescladozgrep
.zcat
é justogunzip -c
. Use a ferramenta certa para o trabalho certo, o KISS é melhor do que inchar. Nesse caso, eu gastaria meu tempo escrevendo algo que gera links físicos, conforme necessário, que é mais divertido.