我可能在这里遗漏了一些信息,但今天当我尝试diff
在两个.html
应该有细微差别的文件上运行并收到此消息时,我感到很惊讶:
$ diff index.html index3.html
Binary files index.html and index3.html differ
为什么.html
文件被视为二进制文件?有什么方法可以避免这种情况并将它们视为文本文件吗?
答案1
GNU 差异将文件视为二进制文件如果前几千字节内有空字节。文本文件不包含空字节,而二进制文件很可能在前几百个字节内包含空字节,因此这是一个很好的启发式方法。文件名并不重要。
diff 不显示二进制文件之间差异的原因是这通常是不可读的。二进制格式通常不能分为在块发生更改后提供有用的重新对齐的行,通常会从根本上更改为较小的语义更改(例如,在压缩文件中插入一个字符可以更改后面的所有内容),并且会导致无法打印diff 输出中的字符。但 diff 可以使用空字节。要强制 diff 将文件视为文本(意思是:显示差异),请传递--text
(或-a
) 选项:
diff --text index.html index3.html
这是否有用取决于文件为何包含空字节。空字节在 HTML 文件中并不常见。你可以得到一个提示
file index.html
如果文件实际上被压缩, diff 将不会显示任何有用的内容:您需要解压缩它,并且应该给它一个反映压缩机制的名称,例如index.html.gz
。如果您有压缩文件,在 bash/ksh/zsh 中,您可以即时解压缩它们(替换uncompress
为从标准输入读取压缩文件并将解压缩文本写入标准输出的实际命令):
diff --label=index.html <(uncompress <index.html) --label=index3.html <(uncompress <index3.html)
您的文件可能采用非 ASCII 编码,例如UTF-16,UCS-2,UTF-32,或 Unicode 之前的多字节编码。这种编码在网络上很少见。 Web 浏览器确实支持它们,但文档制作工具可能会遇到麻烦。如果是这种情况,如果您修改生产链以使用UTF-8反而。同时,diff --text
将给出可能可读或不可读的结果,具体取决于存在的非 ASCII 内容,或者您可以即时转换文件以将它们传递给 diff,例如使用以小端 UTF- 编码的文件16:
diff --label=index.html <(iconv -f UTF-16LE -t UTF-8 <index.html) --label=index3.html <(iconv -f UTF-16LE -t UTF-8 <index3.html)