Diff несколько файлов, правда, если все не равны

18

У меня есть несколько файлов, я хочу убедиться, что все эти файлы имеют одинаковое содержимое.

Какую командную строку я могу использовать, чтобы проверить это?

Использование может быть что-то вроде:

$ diffseveral file1 file2 file3 file4

Результат:

All files equals

ИЛИ

Files are not all equals
Николас Рауль
источник

Ответы:

27

С помощью GNU diff передайте один из файлов в качестве аргумента, --from-fileа любое количество других в качестве операнда:

$ 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
Жиль "ТАК - прекрати быть злым"
источник
4

Как насчет:

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

Вычисляет значение MD5 для каждого файла, затем сравнивает каждую запись со следующей, если они отличаются, и возвращает нулевое (истинное) состояние выхода. Это будет намного короче, если он вернет false, если отличается:

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

Нет необходимости сортировать, так как мы просто проверяем, отличаются ли они.

Arcege
источник
1
В более короткой версии, я думаю, следует использовать $ 1, так как $ 0 содержит уникальное имя файла.
Ксанпен
2

Следующий код должен быть достаточно понятным. $#это число аргументов файла, и shiftтолько потребляет их по одному за раз. Используется cmp -sдля бесшумного побайтного сравнения.

#!/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
источник
0

Вы можете сделать только diffдва, но довольно легко проверить, все ли они равны:

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

Если вам достаточно оправдать цикл, используйте что-то вроде этого:

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
источник
Коряво, если у вас пятьдесят файлов или вы не знаете, сколько
DarenW
1
@ Дарен Конечно, если у вас их много, просто используйте цикл.
Кевин