- 喜欢使用 grep 检测行尾的模式,但对于 CRLF 行终止符的 DOS 文件。
- 像https://unix.stackexchange.com/a/462633/374303,一种方法是使用,
dos2unix
但我的远程服务器中没有它。
即,在扩展正则表达式模式下\r
不起作用?:grep
$ printf 'abcd\r\n' | grep -Ec 'd\r$'
0
$ printf 'abcd\r\n' | grep -c 'd.$'
1
$ printf 'abcd\r\n' | grep -Pc 'd\r$'
1
我认为\r
是扩展正则表达式的一部分,就像
https://valelab4.ucsf.edu/svn/3rdpartypublic/boost/libs/regex/doc/html/boost_regex/syntax/basic_extended.html。不?
或者它确实是一个限制grep
?
答案1
不,\r
不是标准的一部分基本的也不延长正则表达式除了在awk
,尽管有些grep
支持它作为扩展,例如from grep
ast-open ,它支持它的所有正则表达式风格(使用-E
、和默认的 BRE)。-X
-P
perl
不过,它是正则表达式以及 PCRE 表达式的一部分,因此应该得到grep
支持 a 的实现的支持-P
。
现在大多数 shell 支持$'...'
ksh93 的引号形式,其中\r
扩展为回车符。因此,有了这些,你可以这样做:
grep $'d\r$'
(*LF)
PCRE 允许使用诸如, (*CRLF)
,之类的指令指定行分隔符的类型,但即使在使用 PCRE 实现类 perl 匹配的情况下也(*CR)
不能使用它,因为它适用于grep -P
grep
内容一次一行(LF 分隔),因此在正则表达式匹配的字符串中找不到 LF。
但它可以在pcregrep
的M
ultiline 模式下使用:
$ printf '%s\r\n' foo abcd bar | pcregrep -M '(*CRLF)d$' | sed -n l
abcd\r$
(sed -n l
将 CR 显示为\r
)。
使用 GNU grep
,您可以将它与-z
标志一起使用,使其适用于 NUL 分隔的记录而不是行:
$ printf '%s\r\n' foo abcd bar | grep -oPz '(*CRLF)(?m).*d$' | tr '\0' '\n' | sed -n l
abcd$
(除了在记录末尾之外,还启用m
ultiline 标志在每行末尾进行匹配,并在输出时将 NUL 解析为 LF 以进行显示)。$
tr