Grep 在 DOS 格式的文本文件中找不到行尾?

Grep 在 DOS 格式的文本文件中找不到行尾?

在 Ubuntu 中,我正在处理一个 C 文件,该文件最初是在 Windows 下创建的,然后提交给源代码控制。 Vim显示文件格式是“dos”,我收集的只是意味着它有CR/LF行结尾。我想通过使用grep查找正则表达式来获取文件中的函数定义列表')$',但它什么也没返回。当我将文件格式更改为“unix”(:set ff=unixvim)中时,它就grep按预期工作了。

这是一个错误,还是grep官方不支持CR/LF行结尾?我确实在页面上找到了这个man

-U --binary 将文件视为二进制文件。默认情况下,在 MS-DOS 和 MS-Windows 下,grep 会猜测文件是文本还是二进制文件,如 --binary-files 选项所述。如果 grep 确定该文件是文本文件,它将从原始文件内容中删除回车符(以使带有 ^ 和 $ 的正则表达式正常工作)。指定 -U 会推翻这种猜测,导致所有文件被读取并逐字传递给匹配机制;如果文件是每行末尾都有 CR/LF 对的文本文件,这将导致某些正则表达式失败。此选项对 MS-DOS 和 MS-Windows 以外的平台没有影响。

但它确实说在 MS-DOS 和 MS-Windows 下在前面的句子中,所以我不知道这是否适用于这里?

还有其他正则表达式吗应该matchCR/LF或其他一些命令行选项grep我没有看到有帮助?或者,对我来说,通过重新格式化同事的文件来创建一堆提交噪音真的是唯一的解决方案吗?

答案1

在 Windows 和 DOS 文本文件中,每行末尾都有一个额外的回车符。这意味着正则表达式)$不是匹配任何行,因为每行还会有额外的回车符。

要匹配以)回车符结尾的行,请使用)[[:space:]]$as 表达式。该[[:space:]]位将匹配任何单个“类似空格的字符”,其中包括回车符。

您还可以给grep一个文字表达式中的回车,使用eg$')\r$'作为表达式的参数字符串。在某些 shell 中,$'...'是“C 字符串”,shell 会将其中的转义序列(如 、 等)扩展为\t这些在 C 编程语言中表示的实际字符。\r\n

的某些变体grep还可以将表达式识别\s为与回车符匹配(就像使用更便携的那样[[:space:]])。

如果您要在 Unix 系统上使用这些文件,最简单的方法是将文件转换为 Unix 文本文件,使用您在问题中提到的方法(从 Vim 编辑器将其保存为 Unix 文本文件),或者通过使用诸如 之类的工具转换它们dos2unix


“在 MS-DOS 和 MS-Windows 下”的文本指的是grep在那些特定操作系统上运行。这不适用于您,因为您使用的是 Ubuntu。

相关内容