Using grep with negative look-ahead returning no matches - regex

So I am writing a few scripts for migrating SVN to GIT, we have a bunch of "old" branches in SVN that still exist but don't need to be moved to GIT. (Branches which happened to have already been merged to trunk).
After a bit of google-fu I've come up with the following:
$(git for-each-ref --format='%(refname:short)' --merged origin/trunk | grep '(?!origin\/trunk)origin\/.*')
To be passed to
git branch -D --remote _previouscommandgoeshere_
If I run just git for-each-ref --format='%(refname:short)' --merged origin/trunk I get the following output:
origin/IR1091
origin/IR1102
origin/IR1105
...
origin/IR932
origin/Software
origin/trunk
origin/trunk#6792
origin/trunk#6850
When I add the grep command I get 0 values.
However, https://regexr.com/3ot1t has thaught me that my regexp is doing exactly what I want to do. Remove all branches except for the trunk branch.
What is wrong with the regexp/grep? (note I am not a linux/grep guru. This is all done in bash that comes with windows git)

The regexp is right, but grep by default does not support PCRE expression constructs like Negative look-ahead (?!. You need to enable the -P flag to enable the PCRE library, without that it just supports the Basic Regular Expression engine
.. | grep -oP '(?!origin\/trunk)origin\/.*'
Or use a perl regex match on the command line for which no flags need to be set up
.. | perl -ne 'print if /(?!origin\/trunk)origin\/.*/'

grep -P 'origin/(?!trunk)'
just this, can match what your wanted

Related

Could not extract jdk-version using grep-command and regular expressions

I am trying to extract the version of a jdk using regular-expressions Actually I have the following version:
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04, mixed mode,sharing)
I wrote the regex. It looks like the following:
^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}$
This regular expression is working on the online regex tester (https://regex101.com/). Unfortunately, it is not working with grep-command. I am using the extended regular expression. My Code for the extraction of jdk-version look like the following:
CMD_RESULT=$(java --version 2>&1 | head -n 1 | cut -d '' -f 2)
if [ ! -z "$CMD_RESULT" ]
then
for token in $CMD_RESULT
do
JAVA_VERSION=$(echo $token | grep -e $VERSION_EXTRACTION_REGEX)
if [ ! -z $JAVA_VERSION ];
then
printf "${GREEN}Java version: [$JAVA_VERSION]\n"
fi
done
fi
I am not understanding, why my regex is working on the online regex checker, while it is not working with the grep-command. I am using the Parameter -e for extended regexp.
Any Idea ?
A few small changes to OPs current code:
as mentioned in the comments, ^ and $ represent the beginning and ending of the input; remove these from the regex
while grep can use the resulting regex it will be necessary to tell grep to run in -Extended regex mode
we can use grep's -o option to limit output to just the portion that matches the regex
Sample input data:
$ cat jdk.dat
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04, mixed mode,sharing)
One grep solution using OP's modified regex:
$ grep -oE '[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}' jdk.dat
11.0.9.1
11.0.9.1
11.0.9.1
Same thing but with the regex stored in OPs variable:
$ VERSION_EXTRACTION_REGEX='[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}'
$ grep -oE "${VERSION_EXTRACTION_REGEX}" jdk.dat
11.0.9.1
11.0.9.1
11.0.9.1
NOTE: I'll leave it up to the user to decide which value to use, eg, head -n 1 to work with just the first input line (openjdk 11.0.9.1 2020-11-04)
Be done with using only native Bash commands to parse the java version string:
#!/usr/bin/env bash
# Capture java command path if it exists OR exit fail
java_cmd=$(command -v java) || exit 1
# Capture java raw version output
java_raw_version=$("$java_cmd" -version 2>&1)
# Match java raw version string against Bash Regex OR dump debug if match fail
[[ $java_raw_version =~ ([0-9]+)\.([0-9]+)\.([0-9]+)[_.+-]([0-9]+) ]] ||
typeset -p java_raw_version BASH_REMATCH
major=${BASH_REMATCH[1]} # Regex capture group 1
minor=${BASH_REMATCH[2]} # Regex capture group 2
patch=${BASH_REMATCH[3]} # Regex capture group 3
release=${BASH_REMATCH[4]} # Regex capture group 4
# Recompose a semantic version string
semver="$major.$minor.$patch-$release"
printf 'Java semantic version is: %s\n' "$semver"
Sample outputs:
From:
openjdk version "1.8.0_275"
OpenJDK Runtime Environment (build 1.8.0_275-8u275-b01-0ubuntu1~20.10-b01)
OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)
Output:
Java semantic version is: 1.8.0-275
From:
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.18.04, mixed mode,sharing)
Output:
Java semantic version is: 11.0.9-1
About semantic versioning, see: https://semver.org/
Here is a very simple awk solution (no need for regexp):
#!/usr/bin/env bash
# Capture java command path if it exists OR exit fail
java_cmd=$(command -v java) || exit 1
# Capture java raw version output
java_raw_version=$("$java_cmd" -version 2>&1)
# print out the Java version:
echo $java_raw_version | awk -F \" 'NR==1{print "Java semantic version is: "$2}''
Explanation:
-F \" set awk fields separator to "
NR==1 only deal with line #1
print "Java semantic version is: "$2 append 2nd field to text and print

Best way to capture a regex from stdout and pipe match into an xarg command

I am trying to put together a simple script that does a regex on a git clone output and captions the directory that the default clone cmd is cloning too and then captures this into a shell for or something that can then be piped into xargs?
E.g:
git clone git#github.com:thorchain/instaswap-sdk.git |& grep "\'\S*\'" | xargs cd
In this example grep is not the right tool as its output is the matching line and not the match. However, for the life of me, I can't seem to find a simple regex matching tool?
Thanks in adv
Luke
Turns out the missing bit was the grep -o that I needed. What I was trying to do was built a bash function the git cloned and cd into the repos directory.
End solution here:
function gitc() {
cd `git clone "$#" |& grep -o "\'\S*\'" | tr -d "'"`
}

Git alias command with bash script egrep produces different results

Here's an example of pretty basic shell alias in git
[alias]
em = "!git branch --merged | egrep -v '\\*\\|master' | xargs -L 1 -n 1 echo"
It echos the branches that are already merged exluding the master branch (and the current branch you're on). Pretty simple. However the results are different when running this alias and just the script. Example:
will ~/example master
$ git branch --merged | egrep -v '\\*\\|master' | xargs -L 1 -n 1 echo
feature
will ~/example master
$ git em
feature
*
master
For some reason it's like egrep clause isn't even run. In fact (since I'm OS X) it's almost like it ran the grep command instead! Like this: (note the grep vs egrep)
will ~/example master
$ git branch --merged | grep -v '\\*\\|master' | xargs -L 1 -n 1 echo
feature
*
master
Has anybody come across this before?
I've read up on these SO questions and they aren't dealing with the same thing I am. The top one is the closest, but has to do with from where shell command alias are run (the toplevel of the repo).
Why does running command as git alias gives different results?
Bash script produces different result when executed from shell prompt than executed by cron
It appears that the alias definition undergoes some amount of shell processing (or at least backslash processing) before it is defined. Add another set of escaped backslashes to the alias.
[alias]
em = "!git branch --merged | egrep -v '\\\\*\\\\|master' | xargs -L 1 -n 1 echo"

Github search using regex

Is there any way to search code in a github repo using regular expressions?
Currently, I clone the repo and search.
But I want to type something like
s/foo/gi
and find all occurances of foo in the code:
foo.create
foo.extend
fooBar
barFoo
bar.foo
Is this possible? Am I missing something in the docs?
Livegrep allows for interactive regex search of ~gigabyte-scale source repositories.
This is now possible with GitHub Code Search.
Since it's a Git repo, why not just clone it locally, and then use git grep with one of it's regex options?:
git grep [-w | --word-regexp]
[-E | --extended-regexp] [-G | --basic-regexp]
[-P | --perl-regexp]
So maybe something along the lines of
$ git clone repo
$ git grep -w foo
Using the keyword "OR"?
foo.create OR foo.extend OR fooBar OR barFoo OR bar.foo
edit: Oops, I answer next to your needs. sorry.

How do you get Amazon SES working on Debian Squeeze?

All the Perl dependencies for it are met but I'm getting this error:
Can't locate object method "ssl_opts" via package "LWP::UserAgent" at SES.pm line 250.
I just wanted to document what I had to do to get this running on my Debian system. The solution for Ubuntu is probably the same.
First, to let Perl find SES.pm make the directory /usr/local/lib/site_perl and copy SES.pm there. I prefer this solution over what the README recommends.
Your system probably has a lot of the dependencies met already so instead of installing duplicate packages just check first which ones it needs. To do that run these commands. If it gives an error it's not met:
perl -e 'use Crypt::SSLeay'
perl -e 'use Digest::SHA'
perl -e 'use Bundle::LWP'
perl -e 'use LWP::Protocol::https'
perl -e 'use MIME::Base64'
perl -e 'use Crypt::SSLeay'
perl -e 'use XML::LibXML'
I had to remove the package libcrypt-ssleay-perl because it's not compatible with this Amazon script. With it the script produces the error in the question.
I installed these packages from Debian:
libxml-libxml-perl
libssl-dev (needed to compile dependencies)
To find out which package contains the Perl module you need use this page on the Debian site to search the contents of packages:
http://www.debian.org/distrib/packages
Replace the :: in the package with / and put .pm at the end. For example if you need XML::LibXML search for XML/LibXML.pm
I installed these packages from CPAN. It takes a little while though. There are a lot of dependencies.
perl -MCPAN -e 'install LWP::Protocol::https'
perl -MCPAN -e 'install Crypt::SSLeay'
Comment out line 250 in SES.pm, as follows:
# $browser->ssl_opts(verify_hostname => 1);
Then it will run. Probably less secure. But it runs.