117

看起来新版本的 OSX 不再支持grep -P,因此使我的一些脚本停止工作。

var1=`grep -o -P '(?<=<st:italic>).*(?=</italic>)' file.txt`

我需要将 grep 捕获到一个变量中,并且我需要使用零宽度断言,以及\K

var2=`grep -P -o '(property:)\K.*\d+(?=end)' file.txt`

任何替代方案将不胜感激。

4

13 回答 13

118

如果您的脚本仅供您使用,您可以grep使用以下方式homebrew-core安装brew

brew install grep 

然后它可以作为ggrep(GNU grep) 使用。它不会替换系统grep(您需要将已安装的 grep 放在系统之一之前PATH)。

安装的版本brew包含该-P选项,因此您无需更改脚本。

如果你需要使用这些命令的正常名称,你可以从你的 bashrc 中添加一个“gnubin”目录到你的 PATH 中,比如:

PATH="/usr/local/opt/grep/libexec/gnubin:$PATH"

您可以在 ~/.bashrc 或 ~/.zshrc 上导出此行以保留它以供新会话使用。

请参阅此处以了解旧选项的优缺点及其--with-default-names(最近)删除的讨论。

于 2014-03-28T04:44:42.287 回答
75

如果你想做最少的工作,改变

grep -P 'PATTERN' file.txt

perl -nle'print if m{PATTERN}' file.txt

和改变

grep -o -P 'PATTERN' file.txt

perl -nle'print $& while m{PATTERN}g' file.txt

所以你得到:

var1=`perl -nle'print $& while m{(?<=<st:italic>).*(?=</italic>)}g' file.txt`
var2=`perl -nle'print $& while m{(property:)\K.*\d+(?=end)}g' file.txt`

在您的特定情况下,您可以通过额外的工作来实现更简单的代码。

var1=`perl -nle'print for m{<st:italic>(.*)</italic>}g' file.txt`
var2=`perl -nle'print for /property:(.*\d+)end/g' file.txt`
于 2013-05-20T21:27:31.047 回答
13

安装ack并改用它。Ack 是用 Perl 编写的 grep 替代品。它完全支持 Perl 正则表达式。

于 2013-05-20T21:27:20.890 回答
11

OS X 倾向于提供 BSD 而不是 GNU 工具。但是,它确实附带egrep,这可能是您执行正则表达式搜索所需的全部内容。

例子:egrep 'fo+b?r' foobarbaz.txt

OSX grep 手册页的片段:

grep is used for simple patterns and basic regular expressions (BREs); egrep can handle extended regular expressions (EREs).

于 2016-03-30T13:36:43.003 回答
7

use perl;

perl -ne 'print if /regex/' files ...

如果您需要更多grep选项(我看您-o至少会喜欢),pgrep网络上有各种实现,其中许多在 Perl 中。

如果“几乎 Perl”足够好,PCRE 会附带pcregrep.

于 2013-05-20T21:03:00.790 回答
6

还有另一种选择:pcregrep.

Pcregrep是一个与 Perl 兼容的正则表达式的 grep。它的用法与grep -P. 因此它将与您的脚本兼容。

它可以用自制软件安装:

brew install pcre

于 2014-07-27T11:37:00.093 回答
4

使用“-E”选项怎么样?它对我来说很好,例如,如果我想检查php_zip, php_xml,来自php -mphp_gd2的扩展名,我使用:

php -m | grep -E '(zip|xml|gd2)'
于 2016-12-08T01:52:32.850 回答
3

等效于已接受的答案,但不需要 -P 开关,这在我可用的两台机器上都不存在。

find . -type f -exec perl -nle 'print $& if m{\r\n}' {} ';' -exec perl -pi -e 's/\r\n/\n/g' {} '+'
于 2016-05-18T08:17:16.587 回答
2

这个对我有用:

    awk  -F":" '/PATTERN/' file.txt
于 2016-08-15T19:57:49.390 回答
0

-P 的另一个 Perl 解决方案

var1=$( perl -ne 'print $1 if m#<st:italic>([^<]+)</st:italic># ' file.txt)
于 2013-05-20T21:09:19.667 回答
0

通过使用管道传递查找输出来使用 perl 单行正则表达式。我使用了lookbehind(在html中获取src链接)和lookahead for " 并将curl(html)的输出传递给它。

bash-3.2# curl stackoverflow.com | perl -0777 -ne '$a=1;while(m/(?<=src\=\")(.*)(?=\")/g){print "Match #".$a." "."$&\n";$a+=1;}'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  239k  100  239k    0     0  1911k      0 --:--:-- --:--:-- --:--:-- 1919k
Match #1 //ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
Match #2 //cdn.sstatic.net/Js/stub.en.js?v=fb6157e02696
Match #3 https://ssum-sec.casalemedia.com/usermatch?s=183712&amp;cb=https%3A%2F%2Fengine.adzerk.net%2Fudb%2F22%2Fsync%2Fi.gif%3FpartnerId%3D1%26userId%3D
Match #4 //i.stack.imgur.com/817gJ.png" height="16" width="18" alt="" class="sponsor-tag-img">elasticsearch</a> <a href="/questions/tagged/elasticsearch-2.0" class="post-tag" title="show questions tagged &#39;elasticsearch-2.0&#39;" rel="tag">elasticsearch-2.0</a> <a href="/questions/tagged/elasticsearch-dsl" class="post-tag" title="show questions tagged &#39;elasticsearch-dsl&#39;" rel="tag
Match #5 //i.stack.imgur.com/817gJ.png" height="16" width="18" alt="" class="sponsor-tag-img">elasticsearch</a> <a href="/questions/tagged/sharding" class="post-tag" title="show questions tagged &#39;sharding&#39;" rel="tag">sharding</a> <a href="/questions/tagged/master" class="post-tag" title="show questions tagged &#39;master&#39;" rel="tag
Match #6 //i.stack.imgur.com/tKsDb.png" height="16" width="18" alt="" class="sponsor-tag-img">android</a> <a href="/questions/tagged/linux" class="post-tag" title="show questions tagged &#39;linux&#39;" rel="tag">linux</a> <a href="/questions/tagged/camera" class="post-tag" title="show questions tagged &#39;camera&#39;" rel="tag
Match #7 //i.stack.imgur.com/tKsDb.png" height="16" width="18" alt="" class="sponsor-tag-img">android</a> <a href="/questions/tagged/firebase" class="post-tag" title="show questions tagged &#39;firebase&#39;" rel="tag"><img src="//i.stack.imgur.com/5d55j.png" height="16" width="18" alt="" class="sponsor-tag-img">firebase</a> <a href="/questions/tagged/firebase-authentication" class="post-tag" title="show questions tagged &#39;firebase-authentication&#39;" rel="tag
Match #8 //i.stack.imgur.com/tKsDb.png" height="16" width="18" alt="" class="sponsor-tag-img">android</a> <a href="/questions/tagged/ios" class="post-tag" title="show questions tagged &#39;ios&#39;" rel="tag">ios</a> <a href="/questions/tagged/in-app-purchase" class="post-tag" title="show questions tagged &#39;in-app-purchase&#39;" rel="tag">in-app-purchase</a> <a href="/questions/tagged/piracy-protection" class="post-tag" title="show questions tagged &#39;piracy-protection&#39;" rel="tag
Match #9 //i.stack.imgur.com/tKsDb.png" height="16" width="18" alt="" class="sponsor-tag-img">android</a> <a href="/questions/tagged/unity3d" class="post-tag" title="show questions tagged &#39;unity3d&#39;" rel="tag">unity3d</a> <a href="/questions/tagged/vr" class="post-tag" title="show questions tagged &#39;vr&#39;" rel="tag
Match #10 http://pixel.quantserve.com/pixel/p-c1rF4kxgLUzNc.gif" alt="" class="dno
bash-3.2# date
Mon Oct 24 20:57:11 EDT 2016
于 2016-10-25T01:13:07.733 回答
0

I had this same problem with grep suddenly on a docker rebuilt, I found the solution here : https://github.com/firehol/firehol/issues/325

just replaced -oP with -oE

echo $some_var | grep -oE '\b[0-9a-f]{5,40}\b' | head -1

于 2021-09-17T09:19:50.337 回答
-1

更多选项,这些也设置正确的退出状态:

  • 相当于 'grep -P "PATTERN" ' :

    猫文件 | perl -e'while(<>){if( (m!PATTERN!) ){$ok++;print}};if(!($ok)){exit 1}'

  • 相当于 'grep -P -i "PATTERN" ' :

    猫文件 | perl -e'while(<>){if( (m!PATTERN!i) ){$ok++;print}};if(!($ok)){exit 1}'

  • 相当于 'grep -v -P "PATTERN" ' :

    猫文件 | perl -e'while(<>){if( !(m!PATTERN!) ){$ok++;print}};if(!($ok)){exit 1}'

要获得更清洁的解决方案,请使用此要点 - 实现的开关是: -A , -B , -v , -P , -i :https://gist.github.com/torson/bd6931bda0035c4884b2a8c4c64a33b2

于 2022-02-10T20:35:52.580 回答