windows 创建的 txt 文件上的 grep 与 mac 上的字符串不匹配 - 为什么?

windows 创建的 txt 文件上的 grep 与 mac 上的字符串不匹配 - 为什么?

一位同事创建了一个构建树(通过gradle :dependencies > dependencies.txt)并将其通过电子邮件发送给我。我查找了一个我想知道其版本的库,因此我执行了:

grep log4j dependencies.txt

但匹配为零,我的 shell 刚刚打印了一个新的提示。由于它是一个很长的文件并且我信任 grep,所以我没有打开它并检查。经过多次反复讨论后,我被告知该文件是在 Windows 计算机上创建的。即便如此,我还是很惊讶 grep 不起作用 - 搜索字符串不会被换行符打断。但执行后:

dos2unix dependencies.txt

Grep 开始显示我想要的匹配项。

显然我对 grep 工作原理的理解是不正确的。当搜索词之间没有任何换行符时,为什么 grep 对不同操作系统上的文件内容的行为方式不同?

更多信息

  • file dependencies.txt回报dependencies.txt: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
  • LC_ALL=C grep log4j dependencies.txt什么也不返回
  • grep o dependencies.txtBinary file depdencies.txt matches
  • grep --text dependencies.txt什么也没返回

答案1

UTF-16 文本由 16 位片段组成,因此每个字母至少存储在字节。如果只是 ASCII 字符,则每隔一个字节都是一个零字节(NUL 字节,\0而不是字符零)。您的 Mac 很可能没有设置来处理这个问题。

特别是,C 中的 NUL 字节被视为字符串终止符,因此许多工具可能根本无法处理它们。即使他们可以处理它们,他们也可能将每个 NUL 视为不同的字符,因此您需要类似的东西l.o.g.4.j来匹配该字符串。

但有趣的是,NUL 字节在打印时不可见,因此如果您要将cat文件发送到终端,它可能看起来很正常......

NUL 也是 grep 考虑文件二进制的原因。

也可以看看:是什么让 grep 将文件视为二进制文件?

相关内容