一位同事创建了一个构建树(通过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.txt
回Binary 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 将文件视为二进制文件?