当 Windows 行尾的回车符匹配时,如何防止 grep --color 破坏输出?

当 Windows 行尾的回车符匹配时,如何防止 grep --color 破坏输出?

我有一个包含一些行的文件,例如

x
y

当我跑步时

grep -E "x$" filename.txt

它不匹配任何东西。正如 vi^M在大多数行末尾显示的那样,我猜问题是混合了 Dos 和 Unix 换行符以及 grep 自动检测格式。

我试过

grep --color=never -E "x.$" filename.txt

匹配\r行末尾的额外内容并且它可以工作,但是它会打印单个字符\r,因此在--color=always添加终端控制字符时会中断。

我需要的是一个选项,将\r\n$\n与相匹配$

示例文件的十六进制转储:

00000000 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 78 |xxxxxxxxxxxxxxxx|  
00000010 78 78 78 78 78 78 78 78 78 78 780d 0a790a     |xxxxxxxxxxx..y.|

您可以看到 DOS 行结束符和 unix 行结束符。打印该行时,的输出grep -E --color=always "x.$"似乎为空grep -E --color=never "x.$",可能包含与 匹配的回车\r.

答案1

如果您使用 GNU grep,则可以使用\sPCRE 中的符号来匹配任何空白,因此\s*将匹配 0 个或多个空白字符:

$ printf 'x\r\nxx\n' > file
$ grep --color=no -P 'x\s*$' file

xx

请注意,看起来像空行的内容实际上并不是空的,它\r导致终端向后移动并覆盖x*。您可以通过以下方式查看它的实际效果od

$ grep -P 'x\s*$' file | od -c
0000000   x  \r  \n   x   x  \n
0000006

如果您没有 GNU ,您可以以相同的方式grep使用 POSIX 字符类:[:space:]

$ grep 'x[[:space:]]*$' file | od -c
0000000   x  \r  \n   x   x  \n
0000006

使用标准工具(如或 )\r也可以轻松删除:trsed

$ tr -d '\r' < file | grep 'x$'
$ tr -d '\r' < file | grep 'x$'
x
xx
$ sed 's/\r//' file | grep 'x$'
x
xx

* 请注意,正如所解释的@dave_thompson-085,这只会发生,因为我有grep别名,grep --color=auto这意味着颜色代码打印在 周围x,这就是导致x被覆盖的原因,因为它\r导致终端向后移动光标,因此x随后被非打印覆盖颜色转义码。

答案2

我需要的是一个选项,以匹配 \r\n$ 和 \nwith$`。

你可以这样做:

$ grep 'x^M\?$' infile

要键入“^M”,您应该按住该ctrl键,按V,然后ctrl再次按M并按命令行。 A^M将会出现,编码一个carriage return字符。

请理解 grep 的输出将仍然包含一个carriage return.该字符告诉终端将打印位置返回到行首并从那里继续打印。这可能会导致奇怪的后果。

我建议使用 清理文件dos2unix

dos2unix infile >clean.infile

或者甚至(仅作为示例,请不要cat该文件,dos2unix能够直接读取它):

cat infile | dos2unix | grep 'x$'

相关内容