bash - 匹配以 grep 结尾的 unix 行

标签 bash unix grep pcre line-endings

如何匹配以 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

在 Windows 7 上的 MINGW64 上。

最佳答案

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

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

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

演示它正确处理空行和非空行的示例:

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

x
y
baz
$

编辑

上面的解决方案将最后一行视为不包含行尾符号,就好像它以 unix 行结尾一样。例如

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

这可以通过在输入中附加人工 CRLF 来解决 - 如果输入以换行符结尾,则额外的(空)行将被 grep 删除。 ,否则会生成grep删除最后一行:

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

关于bash - 匹配以 grep 结尾的 unix 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41738964/

相关文章:

linux - 在 bash 脚本中用下划线替换连字符

bash - 使用 shell 脚本的内容创建文件

unix - 逆对列的第三列的总和

linux - 如何在 shell 脚本中获取/etc/services 条目?

linux - 使用 sed 从日志文件中提取目录

perl - 从两行中获取字符串

linux - bash rm 删除旧文件只删除第一个

linux - 如何记住 `ln` 命令的参数顺序?

linux - 用于遍历 XML 文件中的 ID 列表并将名称打印/输出到 shell 或输出文件的 BASH 脚本?

python - Travis 脚本退出代码永远不会失败,即使应该失败