Diff, сравнивая только первые n символов каждой строки

У меня есть 2 файла. Назовем их md5s1.txt и md5s2.txt. Оба содержат вывод

find -type f -print0 | xargs -0 md5sum | sort > md5s.txt

в разных каталогах. Многие файлы были переименованы, но контент остался прежним. Следовательно, они должны иметь один и тот же md5sum. Я хочу создать diff как

diff md5s1.txt md5s2.txt

но он должен сравнивать только первые 32 символа каждой строки, т.е. только md5sum, а не имя файла. Линии с равным md5sum следует считать равными. Выход должен быть в нормальном формате.

Ответы

Ответ 1

Легкий стартер:

diff <(cut -d' ' -f1 md5s1.txt)  <(cut -d' ' -f1 md5s2.txt)

Кроме того, рассмотрим только

diff -EwburqN folder1/ folder2/

Ответ 2

Сравните только столбец md5 с помощью diff on <(cut -c -32 md5sums.sort.XXX) и сообщите diff для печати только номеров строк добавленных или удаленных строк, используя --old/new-line-format='%dn'$'\n'. Поместите это в ed md5sums.sort.XXX, чтобы он печатал только те строки из файла md5sums.sort.XXX.

diff \
    --new-line-format='%dn'$'\n' \
    --old-line-format='' \
    --unchanged-line-format='' \
    <(cut -c -32 md5sums.sort.old) \
    <(cut -c -32 md5sums.sort.new) \
    | ed md5sums.sort.new \
    > files-added
diff \
    --new-line-format='' \
    --old-line-format='%dn'$'\n' \
    --unchanged-line-format='' \
    <(cut -c -32 md5sums.sort.old) \
    <(cut -c -32 md5sums.sort.new) \
    | ed md5sums.sort.old \
    > files-removed

Проблема с ed заключается в том, что она загрузит весь файл в память, что может быть проблемой, если у вас много контрольных сумм. Вместо того, чтобы прокладывать вывод diff в ed, подключите его к следующей команде, которая будет использовать гораздо меньше памяти.

diff … | (
    lnum=0;
    while read lprint; do
        while [ $lnum -lt $lprint ]; do read line <&3; ((lnum++)); done;
        echo $line;
    done
) 3<md5sums.sort.XXX

Ответ 3

Если вы ищете дубликаты файлов, fdupes может сделать это за вас:

$ fdupes --recurse

На ubuntu вы можете установить его, выполнив

$ apt-get install fdupes