Diferencia varios archivos, verdadero si no todos son iguales

18

Tengo varios archivos, quiero verificar que todos esos archivos tengan el mismo contenido.

¿Qué línea de comando podría usar para verificar eso?

El uso podría ser algo como:

$ diffseveral file1 file2 file3 file4

Resultado:

All files equals

O

Files are not all equals
Nicolas Raoul
fuente

Respuestas:

27

Con GNU diff, pase uno de los archivos como argumento --from-filey cualquier otro número 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- deja de ser malvado'
fuente
4

Qué tal si:

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

Calcula el valor MD5 para cada archivo, luego compara cada entrada con la siguiente, si alguna es diferente, luego devuelve un estado de salida cero (verdadero). Esto sería mucho más corto si devuelve falso si es diferente:

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

No es necesario ordenar, ya que solo estamos verificando si alguno es diferente.

Arcege
fuente
1
En la versión más corta, supongo que se debe usar $ 1, ya que $ 0 contiene un nombre de archivo único.
xanpeng
2

El siguiente código debería explicarse bastante por sí mismo. $#es el número de argumentos de archivo, y shiftsolo los consume uno a la vez. Usos cmp -spara la comparación silenciosa byte-wise.

#!/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
fuente
0

Solo puede diffdos a la vez, pero es bastante fácil verificar si todos son iguales:

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

Si tiene suficiente para justificar un bucle, use algo como esto:

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
fuente
Torpe si tiene cincuenta archivos, o no sabe cuántos
DarenW
1
@DarenW Claro, si tienes tantos, solo usa un bucle.
Kevin