grep -P no longer works. How can I rewrite my searches?
MacosPerlShellMacos Problem Overview
It looks like the new version of OSX no longer supports grep -P
and as such has made some of my scripts stop working.
var1=`grep -o -P '(?<=<st:italic>).*(?=</italic>)' file.txt`
I need to capture the grep to a variable and I need to use the zero width assertions, as well as \K
var2=`grep -P -o '(property:)\K.*\d+(?=end)' file.txt`
Any alternatives would be greatly appreciated.
Macos Solutions
Solution 1 - Macos
If your scripts are for your use only, you can install grep
from [homebrew-core
][1] using [brew
][2]:
brew install grep
Then it's available as ggrep
(GNU grep
).
[1]: https://github.com/Homebrew/homebrew-core
[2]: http://brew.sh/
it doesn't replaces the system grep
(you need to put the installed grep before the system one on the PATH
).
The version installed by brew
includes the -P
option, so you don't need to change your scripts.
If you need to use these commands with their normal names, you can add a "gnubin" directory to your PATH from your bashrc like:
PATH="/usr/local/opt/grep/libexec/gnubin:$PATH"
You can export this line on your ~/.bashrc or ~/.zshrc to keep it for new sessions.
Please see here for a discussion of the pro-s and cons of the old --with-default-names
option and it's (recent) removal.
Solution 2 - Macos
If you want to do the minimal amount of work, change
grep -P 'PATTERN' file.txt
to
perl -nle'print if m{PATTERN}' file.txt
and change
grep -o -P 'PATTERN' file.txt
to
perl -nle'print $& while m{PATTERN}g' file.txt
So you get:
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`
In your specific case, you can achieve simpler code with extra work.
var1=`perl -nle'print for m{<st:italic>(.*)</italic>}g' file.txt`
var2=`perl -nle'print for /property:(.*\d+)end/g' file.txt`
Solution 3 - Macos
Install ack and use it instead. Ack is a grep replacement written in Perl. It has full support for Perl regular expressions.
Solution 4 - Macos
OS X tends to provide BSD rather than GNU tools. It does come with egrep
however, which is probably all you need to perform regex searches.
example: egrep 'fo+b?r' foobarbaz.txt
A snippet from the OSX grep man page:
Solution 5 - Macos
use perl;
perl -ne 'print if /regex/' files ...
If you need more grep
options (I see you would like -o
at least) there are various pgrep
implementations floating around the net, many of them in Perl.
If "almost Perl" is good enough, PCRE ships with pcregrep
.
Solution 6 - Macos
There is another alternative: pcregrep
.
Pcregrep is a grep with Perl-compatible regular expressions. It has the exactly same usage as grep -P
. So it will be compatible with your scripts.
It can be installed with homebrew:
brew install pcre
Solution 7 - Macos
How about using the '-E' option? It works fine for me,
for example, if I want to check for a php_zip
, php_xml
, php_gd2
extension from php -m I use:
php -m | grep -E '(zip|xml|gd2)'
Solution 8 - Macos
Equivalent of the accepted answer, but without the requirement of the -P switch, which was not present on both machines I had available.
find . -type f -exec perl -nle 'print $& if m{\r\n}' {} ';' -exec perl -pi -e 's/\r\n/\n/g' {} '+'
Solution 9 - Macos
This one worked for me:
awk -F":" '/PATTERN/' file.txt
Solution 10 - Macos
Another Perl solution for -P
var1=$( perl -ne 'print $1 if m#<st:italic>([^<]+)</st:italic># ' file.txt)
Solution 11 - Macos
use the perl one-liner regex by passing the find output with a pipe. I used lookbehind (get src links in html) and lookahead for " and passed the output of curl (html) to it.
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&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 'elasticsearch-2.0'" rel="tag">elasticsearch-2.0</a> <a href="/questions/tagged/elasticsearch-dsl" class="post-tag" title="show questions tagged 'elasticsearch-dsl'" 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 'sharding'" rel="tag">sharding</a> <a href="/questions/tagged/master" class="post-tag" title="show questions tagged 'master'" 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 'linux'" rel="tag">linux</a> <a href="/questions/tagged/camera" class="post-tag" title="show questions tagged 'camera'" 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 'firebase'" 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 'firebase-authentication'" 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 'ios'" rel="tag">ios</a> <a href="/questions/tagged/in-app-purchase" class="post-tag" title="show questions tagged 'in-app-purchase'" rel="tag">in-app-purchase</a> <a href="/questions/tagged/piracy-protection" class="post-tag" title="show questions tagged 'piracy-protection'" 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 'unity3d'" rel="tag">unity3d</a> <a href="/questions/tagged/vr" class="post-tag" title="show questions tagged 'vr'" 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
Solution 12 - Macos
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
Solution 13 - Macos
Some more options, these also set correct exit status:
-
equivalent to 'grep -P "PATTERN" ' :
cat FILE | perl -e'while(<>){if( (m!PATTERN!) ){$ok++;print}};if(!($ok)){exit 1}'
-
equivalent to 'grep -P -i "PATTERN" ' :
cat FILE | perl -e'while(<>){if( (m!PATTERN!i) ){$ok++;print}};if(!($ok)){exit 1}'
-
equivalent to 'grep -v -P "PATTERN" ' :
cat FILE | perl -e'while(<>){if( !(m!PATTERN!) ){$ok++;print}};if(!($ok)){exit 1}'
For a more cleaner solution use this gist - implemented switches are: -A , -B , -v , -P , -i : https://gist.github.com/torson/bd6931bda0035c4884b2a8c4c64a33b2