匹配以 grep 结尾的 unix 行

Match a unix line ending with grep

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

我尝试在 '\r' 上使用负面回顾。

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

为什么那行不通?作为记录,正则表达式模式似乎以这种方式评估得很好:

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

更新:

$ grep --version
grep (GNU grep) 2.24

在 MINGW64 上 windows 7.

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

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

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

演示它正确处理空行和 non-empty 行的示例:

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

x
y
baz
$

编辑

上面的解决方案将最后一行 不包括 end-of-line 符号 视为以 unix 行结束。例如

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

这可以通过在输入中附加一个人工 CRLF 来解决 - 如果输入以换行符结尾,那么多余的(空)行将被 grep 删除,否则会使 grep 删除最后一行:

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