ripgrep 如何用 -E/--encoding 与 BOM 自动嗅探搜索 UTF-16 等非 UTF-8 编码文件 ripgrep 如何用 -E/--encoding 与 BOM 自动嗅探搜索 UTF-16 等非 UTF-8 编码文件【免费下载链接】ripgrepripgrep recursively searches directories for a regex pattern while respecting your gitignore项目地址: https://gitcode.com/GitHub_Trending/ri/ripgrep当你用 ripgrep 搜索一份在 Windows 环境生成的 UTF-16 文本或一份用 cp1251、GBK 这类传统单字节/双字节编码保存的文件时常见现象是模式明明“看起来”就在那个文件里ripgrep 却报告没有匹配。原因在于文件只是一堆字节没有可靠的方式判断其编码而 ripgrep 的正则引擎如 Unicode 感的\w、任意字符.默认按 UTF-8 解释输入。ripgrep 对此提供了三层处理默认的--encoding auto加 BOM 嗅探、用-E/--encoding显式指定编码、以及用-E none退回纯字节搜索。下面按这个顺序说明各自的行为边界和用法。默认行为--encoding auto与 BOM 嗅探GUIDE.md 的 File encoding 一节给出的前提所有输入默认被视为“ASCII 兼容”即每个对应 ASCII 码点的字节确实就是该 ASCII 码点这包括 ASCII 本身、latin1 和 UTF-8。ripgrep 对 UTF-8 支持最好\w、.这类 Unicode 构造假设输入是 UTF-8遇到非 UTF-8 字节时“不会匹配”。--encoding的默认值是auto。按 flags 定义中的长文档auto会对每个文件做“尽力而为”的编码探测但自动探测只适用于以 UTF-8 或 UTF-16 BOM字节顺序标记开头的文件不做任何其他自动检测。针对 UTF-16ripgrep 默认执行所谓“BOM sniffing”读取文件的前三个字节如果对应一个 UTF-16 BOMripgrep 就把文件内容从 UTF-16 转码为 UTF-8再在转码后的内容上执行搜索。两个要点转码会带来性能开销除了正则搜索本身还需要一次转码。如果文件包含无效的 UTF-16 码元Unicode 替换码点replacement codepoint会取代无效码元。所以对一个带 BOM 的 UTF-16 文件最简命令通常直接可用。这是文档中的示例some-utf16-file指代任意包含该字符串的 UTF-16 文件使用时换成你自己的文件$ rg Шерлок some-utf16-file文档的原话是“这个更简单的命令会自动按你预期的方式工作”。FAQ 中也确认了这一点如果你需要搜索 UTF-16 文件又不想手动转码ripgrep 会自动完成无需额外开启见 FAQ.md。注意适用条件只有文件带 BOM 时auto 模式才会触发转码。文件没有 BOM 的 UTF-16 或非 UTF-8 文件不会自动转码此时需要下一条路径。显式指定编码-E/--encoding当文件没有 BOM或整个目录的文件都是同一个已知编码时用-E/--encoding显式指定编码。行为按文档定义可指定的值来自 Encoding Standard 的编码标签列表仓库自带的 shell 补全脚本 encodings.sh 列出了受支持的标签其中包括utf-8、utf-16、utf-16be、utf-16le、cp1250–cp1258、iso-8859-*、koi8、big5、gbk、gb18030、windows-125x等。ripgrep 会假设所有被搜索的文件都是指定编码除非文件带 BOM并执行与 UTF-16 情况相同的转码步骤——即文件被转成 UTF-8 后再搜索你的模式按 UTF-8 书写。取反形式--no-encoding会把编码检测恢复为自动模式auto。以文档中的示例字符串为例如果你的 UTF-16LE 文件没有 BOM可以用显式标签编码标签、模式和文件路径按你的实际情况替换rg -E utf-16le Шерлок some-utf16-file这里utf-16le是 encodings.sh 标签列表中的真实值Шерлок与some-utf16-file沿用 GUIDE.md 的示例值。由于-E作用于本次搜索的全部文件在编码混杂的目录里建议把路径限定到同一编码的文件集合而不是对整个仓库混用。兜底-E none直接搜原始字节-E/--encoding有一个特殊值none完全禁用所有编码相关逻辑包括 BOM 嗅探ripgrep 直接搜索文件的原始字节不做任何转码如果文件带 BOMBOM 本身也会被搜。适合你想按已知字节序列精确定位的场景。文档给出的示例是搜索字符串Шерлок的 UTF-16 原始编码$ rg (?-u)\(\x045\x04\x04;\x04\x04:\x04 -E none -a some-utf16-file两点说明模式中的(?-u)是文档使用的正则标记用于在模式内部关闭 Unicode 支持让模式按字节匹配。文档另举了(?-u:.)的例子使.匹配任意字节而非任意 Unicode 码点适用于搜索二进制文件.默认不匹配无效 UTF-8。命令中的-a/--text不是可省的装饰原因见下一节。与二进制文件检测的交互ripgrep 用“是否含NUL字节”来判定二进制文件而 UTF-16 文本的原始字节里必然大量出现NUL所以按原始字节搜 UTF-16 时文件会被当成二进制。文档描述的三种模式默认模式检测到二进制即停止搜索。该自动跳过只适用于递归目录遍历发现的文件直接指定文件时如rg foo binary-file仍会按 binary 模式搜索该文件。binary 模式对已知二进制文件继续搜到文件末尾或发现匹配为止用--binary强制启用。text 模式-a/--text完全禁用二进制检测所有文件都当文本搜。文档提醒对非常大的二进制文件使用此模式时ripgrep 可能占用大量内存。这就是为什么上面的-E none示例同时带了-a不关二进制检测含 NUL 的 UTF-16 原始字节会先被二进制逻辑拦截。同理如果你要搜的是“主体是文本但含个别 NUL 字节”的文件-a也是文档给出的手段。验证与边界验证方式就是文档展示的两条命令本身带 BOM 的 UTF-16 文件用rg Шерлок some-utf16-file应能直接命中文档示例结果无 BOM 或按字节搜索时用对应标签的-E值或-E none -a组合再搜一次。auto 探测不做“猜测式”检测没有 BOM 就不转码这是默认命令搜不到结果的典型原因不是 bug。转码有性能开销GUIDE.md 明确指出大目录下如果确认全是某一编码显式-E的假设范围是全部被搜文件别在混合编码目录上盲目套用。想确认 ripgrep 实际在做什么GUIDE.md 提到--debug会输出加载的配置文件及从中读取的参数可用于排除配置干扰排查时可加--no-config确保没有配置文件参与。进一步阅读GUIDE.md 的 File encoding 一节与 Binary data 一节、FAQ.md 的“如何搜索非 UTF-8 文件”以及 flags 中-E/--encoding的定义。【免费下载链接】ripgrepripgrep recursively searches directories for a regex pattern while respecting your gitignore项目地址: https://gitcode.com/GitHub_Trending/ri/ripgrep创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考