我想同步两个目录。第一个目录有CRLF正常行尾,第二个目录也有CRLF正常行尾的文件。
问题是,当我执行此代码时:
rsync -azr --exclude=images --dry-run --delete --checksum --out-format="/%f" /dir1 /dir2
Run Code Online (Sandbox Code Playgroud)
它表明将同步许多相同但具有不同编码的文件,而我只想同步不同的内容文件。
使用diff,可以这样做:
diff --strip-trailing-cr file1 file2
Run Code Online (Sandbox Code Playgroud)
但是我找不到 Rsync 这样的东西。如何仅同步具有不同内容的文件?
rsync正如您所发现的,rsync将具有不同行尾的文件视为不同。这在您的情况下很不方便,因为文件在视觉/语义上是相同的。
rsync根据块上的校验和决定在文件中同步什么。对此有一个很好的概述:
(T) 旧版本的文件被分割成块,例如 1024 或 2048 字节,并为每个块计算校验和。
然后逐字节搜索新文件以查找校验和与旧版本匹配的块。这是说明此过程的图表:
在新版本的文件上重复这些操作,您将逐个字节地遍历文件。在此迭代期间,您将在文件中找到两种类型的数据:
- 与旧文件中的块匹配的数据块。
- 不属于匹配块的字节序列。
从rsync的-检测文件差异由雅各布Jenkov。
如果您有兴趣,下一部分将介绍所使用的校验和。但是,校验和的要点是它适用于bytes,并且您的文件由于行尾而具有不同的字节。因此,rsync正确检测到它们是不同的,因此正在传输它们。
最好的办法是确保您的所有文件都具有一致的行尾,或者像Kamil在评论中建议的那样对它们进行消毒。
你如何做到这一点取决于你。您可能决定在生成、编辑或更新文件时进行更改。或者您可以将其作为转移前的步骤。
如果您进行消毒,请确保不要盲目使用,正如 Kamil 进一步警告的那样:
不应盲目地对所有文件使用任何转换工具。即使该工具尝试猜测文件是文本文件还是二进制文件,也只是启发式方法。CRLF 可能出现在二进制文件中;看起来像文本的块也可能出现。通过删除一些字节来修改二进制文件很可能会损坏它。
(强调我的)
例如,如果您知道两个目录中的文件是需要清理的文本文件,则仅将清理步骤应用于该子集。
完整的解决方案超出了本答案的范围。有几个关于这个 SO QA 的建议,包括dos2unix、tr、sed、awk、perl。
例如:
您可以使用
tr从 DOS 到 Unix 的转换;但是,只有当 CR 仅作为 CRLF 字节对的第一个字节出现在您的文件中时,您才能安全地执行此操作。通常是这种情况。然后你使用:Run Code Online (Sandbox Code Playgroud)tr -d '\015' <DOS-file >UNIX-file但是,如果您必须经常这样做(粗略地说不止一次),安装转换程序(例如
dos2unixandunix2dos,或者也许dtouandutod)并使用它们要明智得多。
来自乔纳森莱夫勒的回答。
但是,在使用任何这些工具时,请记住上述警告。
| 归档时间: |
|
| 查看次数: |
2044 次 |
| 最近记录: |