我想同步两个目录。第一个目录有CRLF
和正常行尾,第二个目录中的文件也有CRLF
和正常行尾。
问题是,当我执行此代码时:
rsync -azr --exclude=images --dry-run --delete --checksum --out-format="/%f" /dir1 /dir2
它显示很多相同但编码不同的文件将被同步,而我只想同步不同的内容文件。
使用diff
,可以做到这一点:
diff --strip-trailing-cr file1 file2
但我找不到类似 Rsync 的东西。我怎样才能只同步具有不同内容的文件?
答案1
没有选项可以忽略行尾rsync
正如你所发现的,rsync
考虑具有不同行尾有所不同。这对您的情况来说很不方便,因为文件在视觉/语义上是相同的。
rsync
根据块的校验和决定文件中要同步的内容。有一个对此有很好的概述:
()文件的旧版本被分成多个块,例如 1024 或 2048 字节,并且为每个块计算校验和。
然后逐字节搜索新文件,查找校验和与旧版本匹配的块。下图说明了这个过程:
对新版本的文件重复这些操作,您将逐字节遍历文件。在此迭代过程中,您将在文件中发现两种类型的数据:
- 与旧文件中的块匹配的数据块。
- 不属于匹配块的字节序列。
从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
)并使用它们会更加明智。
然而,使用任何这些工具时请务必牢记上述警告。