匹配以grep结尾的unix行

时间:2017-01-19 10:05:48

标签: bash unix grep pcre line-endings

如何匹配以grep结尾的unix行?我已经有一个使用unix2doscmp的工作脚本,但它有点慢,并且使用其余的bash代码,单个grep命令可以更好地适应。

我尝试在'\r'上使用负面的lookbehind。

$ printf "foo\r\n" | grep -PUa '(?<!'$'\r'')$'
foo

为什么不起作用?为了记录,正则表达式模式似乎很好地评估:

$ printf '(?<!'$'\r'')$' | od -a
0000000   (   ?   <   !  cr   )   $
0000007

更新

$ grep --version
grep (GNU grep) 2.24
在Windows 7上的MINGW64上

1 个答案:

答案 0 :(得分:3)

grep -PUa '(?<!'$'\r'')$'的解决方案使用了更新版本的grep(2.25)。然而,即使在较新版本的grep中,对Perl兼容的正则表达式(-P)的支持也被证明是高度实验性的,因此它在以前的版本中不起作用就不足为奇了。

\([^\r]\|^\)$运行时,使用以下基本正则表达式grep,即以下bash命令:

grep -Ua '\([^'$'\r'']\|^\)$'

一个示例,证明它正确处理空行和非空行:

$ printf "foo\nbar\r\n\nx\n\r\ny\nbaz\n" | grep -Ua '\([^'$'\r'']\|^\)$'
foo

x
y
baz
$

修改

上面的解决方案将最后一行不包括行尾符号视为以unix行结尾结束。 E.g。

$ printf "foo\nbar" | grep -Ua '\([^'$'\r'']\|^\)$'
foo
bar

可以通过在输入中附加一个人工CRLF来修复 - 如果输入以换行结束,那么额外(空)行将被grep删除,否则将使grep放弃最后一行:

$ { printf "foo\nbar"; printf "\r\n"; } | grep -Ua '\([^'$'\r'']\|^\)$'
foo
$