grep匹配回车符的问题

grep匹配回车符的问题

对于不识别CRLF格式文本文件的grep命令(比如Linux和Cygwin下面的grep)来说,回车符(carriage return)\r 并不是有特殊含义的字符,而是普通字符,所以如果要匹配回车符,只需要找到一个能够输入回车符这个字符的方式即可,而bash$'\r' 就能满足要求。下面举例说明。

CVS 在windows的CVS目录下Tag文件是是DOS格式文件文件,把这个文件拷贝到Linux,查看内容如下:

]# cat Tag 
Trelease
]# cat Tag | od -c
0000000   T   r   e   l   e   a   s   e  \r  \n
0000012

现在要匹配行尾的e ,为了对比,我们还建立一个Tag文件的副本TagUnix,使用dos2unix 命令将它转成Unix风格的文本文件,如下所示:

]# cat TagUnix | od -c
0000000   T   r   e   l   e   a   s   e  \n
0000011

使用e$ 作为模式,结果如下

]# grep e$ Tag
]# grep e$ TagUnix 
Trelease

这是说明因为Tag的行尾并不是e ,而是e\r 。那么使用e$'\r'$ 作为模式如何?结果如下:

]# grep e$'\r'$ Tag

]#

得到一个空行输出。这是为什么?这说明,实际上有一行匹配,但是由于这一行的内容包含\r,而它对于终端是有特殊含义的,所以终端就在输出\r的时候,将光标回到行首,于是乎之前输出的内容就看不到,就只能看到一个空行(这似乎说明,Linux下面兼容CRLF格式的不是终端,而是输出文本文件的命令如more, cat等等)。

解决显式效果的办法也简单,重定向到文件,再输出来,或者直接重定向到morecat等命令(是上面重定向到文件的一种特殊情况),或者通过tr命令删除\r,都可以。如下所示:

]# grep e$'\r'$ Tag | more
Trelease
]# grep e$'\r'$ Tag | cat
Trelease
]# grep e$'\r'$ Tag | tr -d '\r'
Trelease

你可能感兴趣的:(命令行)