【问题标题】:Is it possible to perform look behind and look ahead assertions in grep without perl support?是否可以在没有 perl 支持的情况下在 grep 中执行向后看和向前看断言?
【发布时间】:2013-10-18 15:59:55
【问题描述】:

也许像 vi?

我的 perl 等价物是:

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

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

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

但我想知道 greps 本地正则表达式引擎是否支持它。

【问题讨论】:

  • 显然不是,根据this,您可能已经看到了。
  • 没见过,没有。我实际上使用 -P 选项编写了一些单元测试,但是由于 unittest 开始运行可能会从根文件系统中删除内容的测试,所以我切换到使用 chroot 作为软件将运行的环境。不幸的是,没有 perl 支持就没有 grep。所以我只是在寻找一种廉价的方法来改变我现有的表达方式,而不必改变太多。不过还是谢谢。
  • 我明白了。你可以在chroot中安装东西吗? ack grep 显然会做前瞻。
  • 并非微不足道,因为它是从其他地方构建的图像中解压缩的。我将使用awk,因为我有可用的。
  • ack 专门设计为能够作为单个文本文件安装。您可以下载单个 Perl 程序并将其放在您想要的系统上的任何位置。详情请见beyondgrep.com/install

标签: regex awk grep


【解决方案1】:

一些注意事项:

  • grep -P 使用 libpcre,这是一个编译库(用 C 编写,而不是 perl),它与 perl-兼容
  • 如果文件名中有空格,您的awk 命令将不起作用

这个sed 命令会更好一些:

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

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

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

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

这一次,贪婪对我们有利(正则表达式从左到右评估),您将正确提取一个名为 a -&gt; b 的文件,该文件符号链接到 c

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

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

 

但我没有从技术上回答您的问题,即使用 grep 而不使用 -Pgrep 使用 basic and extended POSIX regular expressions(BRE 和 ERE)。即使是 ERE 也无法满足您的需求,因此快速回答是,如果没有 -P,您无法在单个 grep 命令中执行此操作。您可能可以使用多个grep 命令来执行此操作,但这会非常难看,我倾向于说您实际上无法在没有环视或文本替换的情况下执行此操作,这在 BRE 或 ERE 中都不可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2011-02-08
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多