3

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

Проблема в том, когда я выполняю этот код:

  rsync -azr --exclude=images --dry-run --delete --checksum --out-format="/%f" /dir1 /dir2

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

С помощью diff это можно сделать:

diff --strip-trailing-cr file1 file2

Но я не смог найти ничего подобного для Rsync. Как я могу синхронизировать только файлы с различным содержанием?

1 ответ1

4

Для rsync нет возможности игнорировать окончания строк

Как вы узнали, rsync считает файлы с разными окончаниями строк разными. Это неудобно в вашей ситуации, потому что файлы визуально / семантически одинаковы.

rsync решает, что синхронизировать в файле, основываясь на контрольных суммах блоков. На это есть хороший обзор:

(T) старая версия файла разбивается на блоки, например, 1024 или 2048 байтов, и контрольная сумма рассчитывается для каждого блока.

Затем в новом файле выполняется поиск байтов для байтов для блоков с контрольными суммами, совпадающими с теми, что были в старой версии. Вот диаграмма, иллюстрирующая этот процесс:

diffing 1

Повторяя эти операции с новой версией файла, вы будете перебирать файл байт за байтом. Во время этой итерации вы найдете два типа данных в файле:

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

От RSync - Обнаружение различий в файлах Якоб Дженков.

Если вам интересно, следующий раздел посвящен используемым контрольным суммам. Однако основной смысл контрольной суммы заключается в том, что она работает с байтами, а ваши файлы имеют разные байты из-за окончания строки. Таким образом, rsync правильно определяет, что они разные, и передает их.

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

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

Как вы это делаете, зависит от вас. Вы можете решить, что внесете изменения при создании, редактировании или обновлении файлов. Или вы можете сделать это в качестве шага перед передачей.

Применить санитарию только к необходимым файлам

Если вы проводите санитарную обработку, убедитесь, что вы не применяете ее вслепую, поскольку Камил также предупреждает:

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

(акцент мой)

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

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

Полное решение выходит за рамки этого ответа. Есть несколько предложений по этому SO QA, включая dos2unix , tr , sed , awk , perl .

Например:

Вы можете использовать tr для преобразования из DOS в Unix; однако вы можете сделать это безопасно только в том случае, если CR появляется в вашем файле только в качестве первого байта пары байтов CRLF. Обычно это так. Затем вы используете:

tr -d '\015' <DOS-file >UNIX-file

Однако, если вам придется делать это очень часто (более одного раза, грубо говоря), гораздо разумнее установить конверсионные программы (например, dos2unix и unix2dos или, возможно, dtou и utod) и использовать их.

из ответа Джонатана Леффлера.

Однако при использовании любого из этих инструментов учитывайте приведенное выше предупреждение.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .