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

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

Related

How to force Amazon Elastic Beanstalk get-config to quote all strings when ouputting as YAML

I am exporting all AWS ElasticBeanstalk environment variables and piping the output to serve as command line arguments using xargs.
export $(/opt/elasticbeanstalk/bin/get-config --output YAML environment | sed -r 's/: /=/' | xargs)
Most strings in the YAML output from get-config are not quoted, so the above command snippet breaks when it encounters any environment variable with a space in its value, because the export command uses spaces to delimit the beginning of a new key-value pair.
For example, say I have an environment variable called TEST_VARIABLE with a value of THIS STRING. The above command fails with an error:
-bash: export: `THIS STRING': not a valid identifier
In essence, my question is, how do I get /opt/elasticbeanstalk/bin/get-config --output YAML environment to quote all strings?
I'll be using below env.yaml file as example (I don't use AWS BS so I don't know if there would be a heavy syntax difference), next time please provide an edited example:
env.yaml
env1: this the 1st
env2: this the 2nd
In any case, piping to xargs will be hard for quotes to be kept (as they'd end up being interpreted by a shell, but then you'd need to re-quote them).
You should instead try to produce equivalent (several) export lines, to be consumed by the running shell, something on the lines of source <( output with several export x="..." lines) (valid syntax for bash, zsh, and maybe others).
Pasting below two possibilities:
using only sed
Below solution works (I chose single quotes), on the assumption that there's no single-quoted value.
$ sed -E "s/(.+): (.+)/export \1='\2'/" env.yaml
export env1='this the 1st'
export env2='this the 2nd'
$ source <(sed -E "s/(.+): (.+)/export \1='\2'/" env.yaml)
$ env|egrep ^env
env1=this the 1st
env2=this the 2nd
using yq
Use https://github.com/kislyuk/yq for the needed quoting then sed for the : substitution:
$ yq '.. style="single"' env.yaml|sed -e 's/^/export /' -e 's/: /=/'
export env1='this the 1st'
export env2='this the 2nd'
$ source <(yq '.. style="single"' env.yaml|sed -e 's/^/export /' -e 's/: /=/')
$ env|egrep ^env
env1=this the 1st
env2=this the 2nd

Regex to make a word camel case in alpine linux

I have tried this regex in centos
RegEx: echo 'select-value'|sed -r 's/(-)(\w)/\U\2/g'
Output: selectValue
But in alpine i am not getting the output when i tried the below regex
RegEx: echo 'select-value'|sed -r 's/(-)(\w)/\%U\2/g'
Output: select%Uvalue
Expected Output: selectValue
Please suggest the right regex.
Thanks
It seems that alpine uses the busybox sed by default. You have to install the gnu sed (it may be already installed).
In a docker alpine 3.5 container I've tried that one and it worked echo 'select-value'|/bin/sed -r 's/(-)(\w)/\U\2/g'. Mind the /bin/sed part. Gnu sed was already installed in the docker image.
If you have not luck with that you may use awk if available:
echo 'select-value-another-value'|awk -F'-' '{ for(i=1; i<=NF; i++) printf toupper(substr($i,1,1)) substr($i,2);printf "\n"}'
If you don't have to use sed, try perl:
$ echo 'select-value-but-not-that-one'|perl -pe 's/-(\w)/\u$1/g'
selectValueButNotThatOne

Using grep with negative look-ahead returning no matches

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

Are there any differences between Linux and Cygwin which might explain behaviour of Bash regex test?

I'm writing a Bash script to process folders matching a particular regex pattern which during development within a Linux is working as expected.
regex="^([Pp]age\s*)*([1-9][0-9]*.*)"
if [[ "$dir" =~ $regex ]]; then
# do stuff here
fi
# matches
# 'Page 1 james'
# 'Page2 darren'
# '49'
# does not match
# 'NOT THIS Page 1 james'
# 'Page 007'
# 'randomfolder'
However, the same script within a Cygwin environment fails.
Both environments use the same Bash version (4.3.46)
Both environments provide the expected results for the regex using grep.
I'm no regex master so am unsure if I'm missing something with the regex, or if there's a perculiarity of Cygwin which explains why this is failing.
Additional information:
The folders are on a NAS drive, accessed via NFS in Linux, and Samba from Windows. $LANG is en_GB.UTF-8 on all three.

Bamboo Plan script unable to run regex inside bash script

I am new to Bamboo Atlassian environment. I have a question regarding implement Bash script under plan/branch on Bamboo.
I am trying to run a regex inside script stage but I am getting an error:
/tmp/SW-2636-ScriptBuildTask-4921335221935380637.sh: [[: not found
My code:
if [[ ${bamboo.planRepository.branchName} =~ [0-9]+\.[0-9]+R ]]; then
do Blah Blah
else
do something else
fi
I have also tried with singe [] instead of [[ ]] but didn't get.
I ran this script independently as a Bash script and its running fine. Unable to understand how to add regex inside if condition over Bamboo.
Any suggestion/example would be helpful
This will make a trick:
if [ "$(ps -p "$$" -o comm=)" != "bash" ]; then
bash "$0" "$#"
exit "$?"
fi
Add this script at the top of your script to make Bamboo Bash compatible.