是否可以在没有 perl 支持的情况下在 grep 中执行后视和前瞻断言? [英] Is it possible to perform look behind and look ahead assertions in grep without perl support?

查看:22
本文介绍了是否可以在没有 perl 支持的情况下在 grep 中执行后视和前瞻断言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许喜欢 vi?

我的 perl 等效项是:

My perl equivalent is:

grep -Po '(?<=^.L.........s).*(?=s->s)' rsync_itemized.log

找到所有符号链接修改并输出文件名部分.显然,我可以使用 awk:

Which finds all the symlink modifications and outputs the filename part. Obviously, I can use awk:

awk '$1 ~ /^.L........./ { print $2 }' rsync_itemized.log

但我想知道 grep 原生正则表达式引擎是否支持它.

But I was wondering if greps native regex engine supports it.

推荐答案

一些注意事项:

  • grep -P 使用 libpcre,一个编译库(用 C 编写,而不是 perl) 与 perl兼容
  • 如果文件名中有空格,您的 awk 命令将不起作用
  • grep -P uses libpcre, a compiled library (written in C, not perl) that is perl-compatible
  • Your awk command won't work if there is a space in the file name

这个 sed 命令会好一点:

This sed command will work a little better:

sed '/^.L......... /!d; s///; / -> .*/!d; s///'

这将删除与第一个正则表达式不匹配的所有行,然后删除剩余行的匹配部分,然后对第二个正则表达式执行相同操作,将文本留在中间.由于正则表达式是 greedy,第二个正则表达式将变成 a ->b->c 变成 a 即使你想要 a ->b,所以这也不是一个完美的解决方案.

This deletes all lines that do not match the first regex, then removes the matching portion of the remaining lines, then does the same for the second regex, leaving you with the text in the middle. Since regexps are greedy, the second regex will turn a -> b -> c into a even though you wanted a -> b, so this isn't a perfect solution either.

也许你可以直接使用 perl(我假设你在一个系统上,grep 是在没有 libpcre 库的情况下编译的,因此不能做 -P 但也许你仍然可以访问 perl):

Perhaps you can use perl directly (I assume you're on a system for which grep was compiled without the libpcre library and therefore can't do -P but perhaps you still have access to perl):

perl -ne '/^.L.........s(.*)s->s/ and print "$1
"'

这一次,贪婪对我们有利(正则表达式从左到右计算),您将正确提取名为 a -> 的文件.b 符号链接到 c.

This time, greediness works in our favor (regexps are evaluated left to right) and you'll correctly extract a file named a -> b that is symlinked to c.

如果您有 GNU sed(几乎任何 Linux 系统),你可以模仿这个逻辑:

If you have GNU sed (nearly any Linux system), you can mimic that logic:

sed '/^.L.........s(.*)s->s.*/!d; s//1/'

 

但我还没有从技术上回答你的问题,即在没有 -P 的情况下使用 grep.grep 使用 基本和扩展的 POSIX 正则表达式(BRE 和 ERE).即使 ERE 也不能做你想要的,所以快速回答是你不能在没有 -P 的单个 grep 命令中做到这一点.您可能可以使用多个 grep 命令来执行此操作,但这会非常难看,而且我倾向于说您实际上无法在没有环视或文本替换的情况下执行此操作,这两者都不可用在 BRE 或 ERE.

But I haven't technically answered your question, which was about using grep without -P. grep uses basic and extended POSIX regular expressions (BRE and ERE). Even ERE can't do what you're looking for, so the quick answer is that you cannot do this in a single grep command without -P. You might be able to do it with multiple grep commands, but it would be extremely ugly and I'm leaning on saying you actually cannot do it without look-arounds or text replacement, neither of which are available in BRE or ERE.

这篇关于是否可以在没有 perl 支持的情况下在 grep 中执行后视和前瞻断言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆