md5sum de arquivos em duas pastas

md5sum de arquivos em duas pastas

Estou tentando comparar todos os arquivos em duas pastas por meio de um md5sum em um comando. Alguns gostam do seguinte (bash) no Debian:

$ cd ~/FOLDER1
$ md5sum ~/FOLDER2/* | md5sum -c -

A ideia é que a saída dos hashes do primeiro md5sum seja passada para o segundo e usada como arquivo de entrada. No entanto, o teste mostra que ele apenas compara cada arquivo na FOLDER2 consigo mesmo e retorna "OK" para cada um. Acho que a razão pela qual isso não está funcionando é porque a saída dos nomes dos arquivos do primeiro md5sum inclui o caminho completo. Eu olhei, md5deepmas não encontrei nada que me ajudasse lá. Eu sei que é possível fazer o md5sum para uma pasta, gravar os resultados em um arquivo e depois usar esse arquivo como entrada para o segundo md5sum. Eu queria fazer tudo em uma linha por meio de um canal, em vez de usar dois comandos e escrever um arquivo.

Editar: a resposta aceitaaqui(usando diff) pode fazer o que eu quero, mas não sei se diff(corretamente) compara arquivos binários.

Editar: para obter a saída que eu queria usando md5sum (que mostra o nome do arquivo e "OK"), recorri à gravação de um arquivo em lote. Execute com diffFolders.sh ~/FOLDER1 ~/FOLDER2.

#!/bin/bash
HERE=$PWD
cd "$1"
md5sum * > /tmp/md5sum.cmp
cd "$2"
md5sum -c /tmp/md5sum.cmp
cd $HERE

Este script comparará apenas arquivos presentes em ~/FOLDER. Se ~/FOLDER2houver arquivos adicionais, eles não serão comparados e nenhuma saída indicará que eles existem.

Responder1

Você pode usarsubstituição de processopara passar a saída dos 2 md5sum para diff. Diff, neste caso, seria bom porque as saídas do MD5 são texto simples. Algo como:

diff <(md5 ~/FOLDER1/* | awk '{print $4}') <(md5 ~/FOLDER2/* | awk '{print $4}')

Desculpe, não tenho Debian aqui e não posso testar isso nele. O texto acima foi testado no OS X que possui md5, que pode ser um pouco diferente em termos de saída. No OS X, a quarta coluna do md5 é a soma real do md5, é por isso que estou pegando apenas essas colunas.

Em vez de awk, você também pode usar cut, mas pode ser necessário alterar o separador para obter a quarta coluna (elas não são separadas por tabulações).

Responder2

Do meu arquivo .bashrc.
coisas muito antigas, deve ser possível escrever muito código de classificação. Nunca tive tempo de reescrevê-lo. (como tudo o mais que foi feito para uma correção temporária, usado para sempre) Estou postando este código vergonhoso, espero que alguém possa fazer melhor e postar o resultado :-)

Características :

  • Dir transversal recrusivo
  • md5sum verifica exclusividade/diferença
  • Lista os arquivos atualizados no caminho completo

O código diz tudo. arg1 é o diretório antigo, arg2 é o novo diretório.

function find-updated-files-between-old-new(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( ( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n")
 )|sort -k1.2|tee 1>/dev/null >(uniq -us1|awk -v B="$2" 'BEGIN{sub("/$",""B)}/^-/{print B substr($0,3);
 }') >(uniq -ds1|awk -vA="$1" -vB="$2" 'BEGIN{B=g(B);A=g(A)}{
 C=substr($0,3);if(f(A)!=f(B))print B C;}function g(y){sub("/$","",y);return y}
 function f(y,z,e){e="md5sum \""y""C"\"";e|getline z;close(e);return substr(z,1,32)}' )
 ) | cat
}

Como o nome da função indica

function find-files-name-collision-between-dir1dir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n") )|sort -k 1.2 | uniq -d -s 1
}

Apenas para completar

function mv-mergedir1todir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." && return 1;
 ( cd "$1" ; tar cf - . ) | (cd "$2" ; tar --keep-old-files xvf - )
 echo -e "Done. Duplicate filnames are not replaced. \n#Use \n# ( cd \"$1\" ; tar cf - . ) | (cd \"$2\" ; tar --overwrite xvf - ) \n#if you do not like that. "
}

Este horrível pedaço de código deveria ser removido do meu bashrc, porém ele já existe há muito tempo...

Responder3

Meio longo, mas retorna o nome do arquivo e OK se corresponderem. Em vez de usar '-c', basta comparar as duas strings resultantes da execução do md5sum no arquivo de cada pasta.

for f in *; do [[ -f $f ]] && if [ $(md5sum "$f" | cut -d" " -f1) == $(md5sum dir2/"$f" | cut -d" " -f1) ]; then echo "$f" "OK"; else echo "$f" "MODIFIED"; fi; done

informação relacionada