How do I get the VersionName from this string? - bash

I have this string:
package: name='my.package.name versionCode='221013140' versionName='00.00.05' platformBuildVersionName='12' platformBuildVersionCode='32' compileSdkVersion='32' compileSdkVersionCodename='12'
Using bash, how can I get this value?
00.00.05

Use parameter expansion:
#!/bin/bash
string="package: name='my.package.name versionCode='221013140' versionName='00.00.05' platformBuildVersionName='12' platformBuildVersionCode='32' compileSdkVersion='32' compileSdkVersionCodename='12'"
version=${string#* versionName=\'} # Remove everything up to the version name.
version=${version%%\'*} # Remove everything after the first quote.
echo "$version"

You can use bash regex matching operator (=~):
[[ $string =~ versionName=\'([^\']*)\' ]] && echo "${BASH_REMATCH[1]}"

Related

bash read between two strings using parameter expansion expression

This is how my input string looks like:
INPUT_STRING="{/p1/p2=grabthistext}"
I want to print grabthistext from the INPUT_STRING.
I tried echo "${INPUT_STRING##*=}" which prints grabthistext}
How do I read only grabthistext using parameter expansion expression?
If you really want a single parameter expansion then you can use:
#!/bin/bash
shopt -s extglob
INPUT_STRING="{/p1/p2=grabthistext}"
echo "${INPUT_STRING//#(*=|\})}"
grabthistext
I would use a bash regex though:
#!/bin/bash
INPUT_STRING="{/p1/p2=grabthistext}"
[[ $INPUT_STRING =~ =(.*)} ]] && echo "${BASH_REMATCH[1]}"
grabthistext
temp="${INPUT_STRING##*=}"
echo "${temp%\}}"
grabthistext
You can do it in two steps: first extract the fragment after = as you already did, and store it in a new variable. Then use the same technique to remove the undesired } suffix:
INPUT_STRING="{/p1/p2=grabthistext}"
TEMP_STRING=${INPUT_STRING##*=}
OUTPUT_STRING=${TEMP_STRING%\}}
echo "$OUTPUT_STRING"
# grabthistext
Check it online.

Remove leading digits from a string with Bash using parameter expansion

The initial string is RU="903B/100ms"
from which I wish to obtain B/100ms.
Currently, I have written:
#!/bin/bash
RU="903B/100ms"
RU=${RU#*[^0-9]}
echo $RU
which returns /100ms since the parameter expansion removes up to and including the first non-numeric character. I would like to keep the first non-numeric character in this case. How would I do this by amending the above text?
You can use BASH_REMATCH to extract the desired matching value:
$ RU="903B/100ms"
$ [[ $RU =~ ^([[:digit:]]+)(.*) ]] && echo ${BASH_REMATCH[2]}
B/100ms
Or just catch the desired part as:
$ [[ $RU =~ ^[[:digit:]]+(.*) ]] && echo ${BASH_REMATCH[1]}
B/100ms
Assuming shopt -s extglob:
RU="${RU##+([0-9])}"
echo "903B/100ms" | sed 's/^[0-9]*//g'
B/100ms

How to extract a substring from a URL in bash

I have the following string
git#bitbucket.org:user/my-repo-name.git
I want to extract this part
my-repo-name
With bash:
s='git#bitbucket.org:user/my-repo-name.git'
[[ $s =~ ^.*/(.*)\.git$ ]]
echo ${BASH_REMATCH[1]}
Output:
my-repo-name
Another method, using bash's variable substitution:
s='git#bitbucket.org:user/my-repo-name.git'
s1=${s#*/}
echo ${s1%.git}
Output:
my-repo-name
I'm not sure if there's a way to combine the # and % operators into a single substitution.

check for string format in bash script

I am attempting to check for proper formatting at the start of a string in a bash script.
The expected format is like the below where the string must always begin with "ABCDEFG-" (exact letters and order) and the numbers would vary but be at least 3 digits. Everything after the 3rd digit is a do not care.
Expected start of string: "ABCDEFG-1234"
I am using the below code snippet.
[ $(echo "$str" | grep -E "ABCDEFG-[0-9][0-9][0-9]") ] && echo "yes"
str1 = "ABCDEFG-1234"
str2 = "ABCDEFG-1234 - Some more text"
When I use str1 in place of str everything works ok and yes is printed.
When I use str2 in place of str i get the below error
[: ABCDEFG-1234: unary operator expected
I am pretty new to working with bash scripts so any help would be appreciated.
If this is bash, you have no reason to use grep for this at all; the shell has built-in regular expression support.
re="ABCDEFG-[0-9][0-9][0-9]"
[[ $str =~ $re ]] && echo "yes"
That said, you might want your regex to be anchored if you want a match in the beginning rather than anywhere in the content:
re="^ABCDEFG-[0-9][0-9][0-9]"
[[ $str =~ $re ]] && echo "yes"
That said, this doesn't need to be an ERE at all -- a glob-style pattern match would also be adequate:
if [[ $str = ABCDEFG-[0-9][0-9][0-9]* ]]; then echo "yes"; fi
Try grep -E "ABCDEFG-[0-9][0-9][0-9].*"

BASH: Everything but not slash? IF STATEMENT (STRING COMPARISION)

I'm trying to match any strings that start with /John/ but does not contain / after /John/
if
[ $string == /John/[!/]+ ]; then ....
fi
This is what I got and it doesn't seem to be working.
So I tried
if
[[ $string =~ ^/John/[!/]+$ ]]; then ....
fi
It still didn't work, and so I changed it to
if
[[ $string =~ /John/[^/] ]]; then ....
fi
It worked but will match with all the strings that has / behind /John/ too.
For bash you want [[ $string =~ /John/[^/]*$ ]] -- the end-of-line anchor ensures there are no slashes after the last acceptable slash.
How about "the string starts with '/John/' and doesn't contain any slashes after '/John/'"?
[[ $string = /John/* && $string != /John/*/* ]]
Or you could compare against a parameter expansion that only expands if the conditions are met. This says "after stripping off everything including and after the last slash, the string is /John":
[[ ${string%/*} = /John ]]
In fact, this last solution is the only entirely POSIXLY_STRICT one I can come up with without multiple test expressions.
[ "${string%/*}" = /John ]
By the way, your problem is probably simply be using double-equals inside a single-bracket test expression. bash actually does accept them inside double-bracket test expressions, but a single equals is a better idea.
You can also use plain old grep:
string='/John Lennon/Yoko Ono'
if echo "$string" | grep -q "/John[^/]" ; then
echo "matched"
else
echo "no match found"
fi
This only fails if /John is at the very end of the string... if that's a possibility then you can tweak to handle that case, for instance:
string='/John Lennon/Yoko Ono'
if echo "$string" | grep -qP "(/John[^/])|(/John$)" ; then
echo "matched"
else
echo "no match found"
fi
Not sure what language you're using, but normal negative character classes are prefixed with a ^
e.g.
[^/]
You can also put in start/end qualifiers (clojure example, so Java's regex engine). Usually ^ at beginning and $ at end.
user => (re-matches #"^/[a-zA-Z]+[^/]$" "/John/")
nil

Resources