今天尝试使用grep
时,我遇到了 Unicode 文件(在本例中为 UTF-8 )中的字节顺序标记 (BOM)的熟悉问题。具体来说,我试图找到一个以 pattern开头的文件,但当然将 BOM 视为三个单独的字符,如果第一行以 . 开头,则与文件的第一行不匹配。我什至尝试更新正则表达式以忽略空格(),但无济于事。XYZ
grep '^XYZ'
grep
XYZ
'^[[:space:]]*XYZ'
其他问题涉及转换文件或专门针对 BOM,但我想知道 POSIX 工具是否具有正确处理 Unicode 文件的通用选项。如果grep
正确处理 Unicode 文件,它将认为文件内容在 BOM 之后开始并XYZ
在第一行匹配,就像任何其他行一样。
Unicode 联盟有一个常见问题解答,其中包括我应该如何处理 BOM。这部分包括:
和
请注意,UTF-8始终具有已知的字节序,因为它没有字节序。所以只要你知道文本是 UTF-8,“不应该使用 BOM”。
当不必要地使用 BOM 时,甚至
cat
会返回不正确的结果,因为除第一个文件之外的所有文件的 BOM 将被视为零宽度不间断空格。但是,UNIX 的强大之处在于过滤器。对于单个文件或流上的操作,
sed "1s/^$(printf '\357\273\277')//"
在管道中将剥离 BOM(如果存在),而使所有其他流保持不变。对于具有多个文件的操作,具有进程替换的 shell(如 Bash,但不幸的是不是 POSIX shell)很有用:
大多数 POSIX 工具对字节而不是字符进行操作。Unicode 信号对他们来说毫无意义,因此它会像任何其他数据一样被对待。
从另一个答案来看,听起来我正在处理具有不正确 BOM 签名的文件。
因此,答案是POSIX 工具已经正确处理 Unicode (UTF-8) 文件。
如果您有错误的 Unicode,他们当然不能正确处理它,但是您可以使用其他问题中的 BOM 目标来处理多余的 BOM 签名。