Como posso comparar arquivos diferentes sem abri-los?

Como posso comparar arquivos diferentes sem abri-los?

Tenho dois diretórios A e B; cada um contém muitos subdiretórios

geom001, geom002 ....etc

cada subdiretório contém um arquivo chamado resultados. Quero comparar, sem abrir nenhum deles, cada arquivo em A com cada arquivo em B e descobrir se existe um arquivo ou mais em A semelhante a um ou mais arquivos em B. Como posso usar comandos como o seguinte em um loop para pesquisar todos os arquivos?

cmp --silent  file1 file2  || echo "file1 and file2 are different"

Responder1

Se os arquivos forem exatamente iguais, então seus md5sums serão exatamente iguais, então você pode usar:

find A/ B/ -type f -exec md5sum {} + | sort | uniq -w32 -D

Um md5sum tem sempre exatamente 128 bits (ou 16 bytes ou 32 dígitos hexadecimais) e a md5sumsaída do programa usa dígitos hexadecimais. Portanto, usamos a -w32opção do uniqcomando para comparar apenas os primeiros 32 caracteres de cada linha.

Isto irá imprimirtodosarquivos com um md5sum não exclusivo. ou seja, duplicatas.

NOTA: isso detectará arquivos duplicados, não importa onde eles estejam em A/ ou B/ - portanto, se /A/subdir1/filee A/subdir2/otherfileforem iguais, eles ainda serão impressos. Se houver várias duplicatas, todas serão impressas.

Você pode remover os md5sums da saída canalizando, por exemplo, awk '{print $2}'ou com cutou sedetc. Eu os deixei na saída porque eles são uma chave útil para uma matriz associativa (também conhecida como 'hash') em awkou perletc para mais em processamento.

Responder2

Acho que isso vai te aproximar. Ele listará a saída cmp para todos os arquivos nomeados resultados em A em comparação com todos os arquivos nomeados resultados em B.

find ./A -name results | xargs -I REPLACESTR find ./B -name results -exec cmp REPLACESTR {} \;

Responder3

Os aparentes desafios da pergunta/solicitação talvez sejam o aspecto da recursão.

Supondo que cmpseja um utilitário adequado e que ambas as pastas/diretórios 1e 2a serem comparados tenham a mesma estrutura (ou seja, os mesmos arquivos e pastas) e residam no mesmo caminho raiz - você pode tentar algo semelhante a:

#!/bin/bash
ROOT=$PWD ; # #// change to absolute path eg: /home/aphorise/my_files
PWD1="1/*" ;
PWD2="2/*" ;

# #// Get lengths of seperators
IFS=/ read -a DP <<< ${ROOT} ;
PLEN1=${#DP[*]} ;
IFS=/ read -a DP <<< ${PWD1} ;
PLEN1=$(echo "${#DP[*]}" + $PLEN1 - 1 | bc) ;
IFS=/ read -a DP <<< ${PWD2} ;
PLEN2=${#DP[*]} ;

# #// Set absolute paths:
PWD1="${ROOT}/${PWD1}" ;
PWD2="${ROOT}/${PWD2}" ;
DIFFS=0 ;

function RECURSE()
{
    for A_FILE in $1 ; do
        if [ -d $A_FILE ] ; then
            RECURSE "$A_FILE/*" ;
        else
            IFS=/ read -a FP <<< ${A_FILE} ;
            B_FILE="${PWD2:0:${#PWD2}-${#PLEN2}}$( IFS=/ ; printf "%s" "${FP[*]:$PLEN1:512}"; )" ;
            if ! cmp ${A_FILE} ${B_FILE} 1>/dev/null ; then printf "$A_FILE --> $B_FILE <-- DIFFER.\n" ; ((++DIFFS)) ; fi ;
        fi ;
    done ;
}

printf "Starting comparison on $PWD1 @ $(date)\n\n" ;
RECURSE "${PWD1[*]}" ;
if ((DIFFS != 0)) ; then printf "\n= $DIFFS <= differences detected.\n" ; fi ;
printf "\nCompleted comparison @ $(date)\n" ;

ATUALIZAR:

Seguindo com outro script - após feedback adicional recebido - para comparar incondicionalmente todos os arquivos no diretório 1com 2:

#!/bin/bash
PWD1="$PWD/1/*" ;
PWD2="$PWD/2/*" ;
DIFFS=0 ;
NODIFFS=0 ;

printf "Starting comparison on $PWD1 @ $(date)\n\n" ;

FILES_A=$(find ${PWD1} -type f) ;
FILES_B=$(find ${PWD2} -type f) ;

for A_FILE in ${FILES_A[*]} ; do
        for B_FILE in ${FILES_B[*]} ; do
                if ! cmp ${A_FILE} ${B_FILE} 1>/dev/null ; then
                        printf "$A_FILE & $B_FILE <- DIFFER.\n" ;
                        ((++DIFFS)) ;
                else
                        printf "\n-> SAME: $A_FILE & $B_FILE\n" ;
                        ((++NODIFFS)) ;
                fi ;
        done ;
done ;

printf "\n= $DIFFS <= differences detected - & - $NODIFFS <= exact matches.\n" ;
printf "\nCompleted comparison @ $(date)\n" ;

informação relacionada