использование rsync для быстрого отображения только файлов с различным содержимым

Вопрос или проблема

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

Для моих целей мне нужно найти только файлы, которые действительно отличаются. Если я запущу:

rsync --dry-run -HPrlt

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

Я также подумал попробовать:

rsync -c --dry-run -HPrlt

Но эта команда выполняется намного дольше. Фактически, первая команда выполнялась за несколько секунд (предположительно потому, что структура каталогов уже была в кэше от предыдущего rsync), в то время как последняя команда все еще выполняется. Я подозреваю, что это связано с тем, что rsync полностью полагается на контрольную сумму для определения того, какие файлы нужно передавать, вместо чего-то немного более разумного, например, использования контрольной суммы только в случае, если временные метки отличаются.

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

Примечание: Это не дубликат Как показать файлы, которые были бы изменены с использованием rsync?
потому что, как указывает самый высоко оцененный комментарий к самому высоко оцененному ответу, --dry-run будет показывать файлы, которые идентичны, если их временные метки различаются.

rsync -HPrl --itemize-changes --dry-run source/ destination/ | grep -Fv "f..T......"| grep -Fv "d..T......"| cut -d " " -f 2-

*Не пропустите завершающий слэш для каталога источника.

--itemize-changes выводит сводку изменений для всех обновлений. В сочетании с --dry-run и отфильтровыванием файлов/каталогов, для которых требуется только обновление временной метки, дает необходимый вывод (быстро).

Можно выполнить rsync в два этапа:

  1. Сгенерировать список всех файлов, отличающихся по размеру или временной метке
    (что может включать некоторых файлов, которые идентичны)
  2. rsync, используя этот список и опцию сравнения контрольных сумм
    для нахождения реальных отличий.

Этот ответ основан на посте
Повторное использование вывода rsync –dry-run для ускорения фактической передачи позже.

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

Пример вывода:

sending incremental file list
[СПИСОК ФАЙЛОВ]

sent 226 bytes  received 34 bytes  520.00 bytes/sec
total size is 648,373,274  speedup is 2,493,743.36 (DRY RUN)

Чтобы удалить избыточные строки и оставить только список файлов:

rsync --dry-run -avz source/ destination/ | head --lines=-3 | tail --lines=+3 > include.txt

Для rsync, чтобы использовать этот файл (добавьте дополнительные параметры по желанию):

rsync -c --include-from=include.txt --exclude=* source/ destination/

ИЗМЕНЕНИЕ: Я воспроизвел проблему согласно посту автора
gist
и могу добавить к описанию, что всякий раз, когда указан --dry-run,
все файлы помечаются для синхронизации, независимо от того,
какая комбинация параметров используется.

Я думаю, что проблема на самом деле заключается в --dry-run,
возможно, потому что он проверяет слишком много атрибутов метаданных.
Кажется, это может быть ошибкой.

Это может быть XY проблема: у вас есть проблема, которую нужно решить, но вы спрашиваете, как решить ее с помощью rsync.

Вопрос автора касается rsync, но возможно, что различие во времени всегда будет показано как “разное”. Я не уверен, есть ли опция “-c, но игнорировать временную метку”. Независимо от того, какой инструмент вы решите использовать, вы должны прочитать весь файл, чтобы проверить его содержимое.

Вот возможное альтернативное (не rsync) решение:

Хешируйте деревья и находите отличия. Это создаст список файлов, которые отличаются. Под “отличаются” я имею в виду любое из:

  • содержимое изменилось
  • файл существует с одной стороны, но не с другой
cd /tree1
find -type f -print0 | sort -z | xargs -0 md5sum > /tmp/tree1.log

cd /tree2
find -type f -print0 | sort -z | xargs -0 md5sum > /tmp/tree2.log

diff -uw /tmp/tree1.log /tmp/tree2.log | grep '^[+-]' | awk '{print $2}' | sort -u

(Для скептиков по поводу md5: Я знаю, что md5 устарел с точки зрения поиска второй предобраза… но автор (вероятно) не ищет что-то криптографически критичное, и md5 быстрее, чем sha256.)

Ответ или решение

Для эффективного выявления различий между файлами, находящимися на разных дисках, с помощью утилиты rsync, важно применять правильные параметры, которые позволят избежать лишних данных, таких как различия по времени. Давайте разберем предложенное решение и его преимущества, а также альтернативные методы для достижения вашей цели.

Условия и требования

Имеются два диска с большим количеством файлов, которые в большинстве своем идентичны, однако некоторые файлы различаются по содержимому. Применение команд rsync --dry-run -HPrlt и rsync -c --dry-run -HPrlt в вашей ситуации не приводит к желаемому результату: первая команда учитывает также различия по времени, а вторая выполняется слишком медленно, так как основана исключительно на контрольных суммах.

Оптимальное использование rsync

Применение rsync с флагами --itemize-changes и фильтрация результатов с помощью grep позволяет быстро получить список файлов с реальными различиями. Вот пример команды:

rsync -HPrl --itemize-changes --dry-run source/ destination/ | grep -Fv "f..T......" | grep -Fv "d..T......" | cut -d " " -f 2-

Объяснение параметров:

  • -H — сохраняет символические ссылки.
  • -P — выводит прогресс и продолжает после прерывания.
  • -r — рекурсивное копирование директорий.
  • -l — копирование символических ссылок.
  • --itemize-changes — выводит сводку изменений, что позволяет проводить фильтрацию.
  • --dry-run — симуляция процесса, без изменения данных.

Фильтрация с помощью grep позволяет исключить строки, где различаются только временные метки, оставляя только файлы с измененным контентом.

Альтернативный подход: два этапа

Существует также возможность использования rsync в два этапа для более точного определения файлов с отличающимся содержанием:

  1. Генерация списка всех файлов с различиями в размере или временных метках.
  2. Повторное использование этого списка для более тщательной проверки с помощью опции по контрольным суммам.

Чтобы создать этот список, выполните команду:

rsync --dry-run -avz source/ destination/ | head --lines=-3 | tail --lines=+3 > include.txt

После того как файл include.txt будет сгенерирован, можно использовать его для второй проверки:

rsync -c --include-from=include.txt --exclude=* source/ destination/

Альтернативные методы

Если использование rsync по каким-то причинам не подходит, можно использовать альтернативный метод с хэшированием файлов. Для этого выполните следующие шаги:

  1. Сгенерируйте хэши файлов в каждой директории:
cd /tree1
find . -type f -print0 | sort -z | xargs -0 md5sum > /tmp/tree1.log

cd /tree2
find . -type f -print0 | sort -z | xargs -0 md5sum > /tmp/tree2.log
  1. Сравните файлы:
diff -uw /tmp/tree1.log /tmp/tree2.log | grep '^[+-]' | awk '{print $2}' | sort -u

Заключение

Таким образом, использование rsync с правильными параметрами и корректная фильтрация вывода позволяют эффективно находить различия между файлами. Альтернативные методы, такие как создание хэшей и сравнение, также могут быть полезными и обеспечивают дополнительный уровень точности.

В зависимости от ваших предпочтений и конкретных обстоятельств, выберите наиболее подходящий метод для выполнения вашей задачи. Эффективное решение проблемы позволит сэкономить время и минимизировать количество лишней работы при анализе файлов.

Оцените материал
Добавить комментарий

Капча загружается...