Difere vários arquivos, verdadeiro se todos não forem iguais

18

Eu tenho vários arquivos, quero verificar se todos esses arquivos têm o mesmo conteúdo.

Qual linha de comando eu poderia usar para verificar isso?

O uso pode ser algo como:

$ diffseveral file1 file2 file3 file4

Resultado:

All files equals

OU

Files are not all equals
Nicolas Raoul
fonte

Respostas:

27

Com o GNU diff, passe um dos arquivos como argumento para --from-filee qualquer número de outros como operando:

$ diff -q --from-file file1 file2 file3 file4; echo $?
0
$ echo >>file3
$ diff -q --from-file file1 file2 file3 file4; echo $?
Files file1 and file3 differ
1
Gilles 'SO- parar de ser mau'
fonte
4

E se:

md5sum * | awk 'BEGIN{rc=1}NR>1&&$1!=last{rc=0}{last=$1}END{exit rc}'

Calcula o valor MD5 para cada arquivo, compara cada entrada com a próxima, se houver alguma diferente, e retorna um status de saída zero (verdadeiro). Isso seria muito mais curto se retornasse falso se diferente:

md5sum * | awk 'NR>1&&$1!=last{exit 1}{last=$1}'

Não há necessidade de classificar, pois estamos apenas verificando se são diferentes.

Arcege
fonte
11
Na versão mais curta, acho que $ 1 deve ser usado, pois $ 0 contém o nome do arquivo que é único.
Xanpeng
2

O código a seguir deve ser bastante auto-explicativo. $#é o número de argumentos do arquivo e os shiftconsome um de cada vez. Usa cmp -spara comparação silenciosa em bytes.

#!/bin/sh
# diffseveral

if [ $# -lt 2 ]; then
    printf '%s\n' "Usage: $0 file1 file2 [files ...]" >&2
    exit 2
fi

oldfile="$1"
shift

while [ $# -gt 0 ]; do
    newfile="$1"
    if ! cmp -s "$oldfile" "$newfile"; then
         echo 'Files differ.'
         exit 1;
    fi

    shift
done

echo 'All files identical.'
exit 0
jw013
fonte
0

Você pode apenas diffdois de cada vez, mas é bastante fácil verificar se todos são iguais:

if diff file1 file2 && diff file2 file3 && diff file3 file4; then
    echo All equal
else
    echo Not
fi

Se você tiver o suficiente para justificar um loop, use algo como isto:

alleq () {  
    for file; do 
        diff -q "$1" "$file" >/dev/null || return 1
    done
}

if alleq file1 file2 ...; then
    echo All equal
else 
    echo Not
fi
Kevin
fonte
Desajeitado, se você tem cinquenta arquivos, ou não sabe quantos
darenw
11
@ DarenW Claro, se você tiver muitos, basta usar um loop.
21413 Kevin