Bash comparison check to accept values only with format 0.1 - regex

I have this snippet:
if [[ $1 =~ ^[+-]?[0-9]+\.?[0-9]*$ ]]; then
echo 'version is good'
exit 0
else
exit 1
fi
The problem is that, the snippet $1 =~ ^[+-]?[0-9]+\.?[0-9]*$ should only validate versions formatted as number.number
Currently this chunk of code validates inputs as
1
01
0.1
Is there any way of making the code to only accept inputs formatted as 0.1 / 0.3.2 / 0.1.141 etc.
Thanks in advance.
EDIT:
To clarify this question, the code should only accept numbers separated with dots, like software program versioning.

I suggest this regex: ^[0-9]+(\.[0-9]+){1,2}$

I propose without regex :
[[ "0" == ?([+-])+([0-9]).+([0-9.]) ]] && echo OK # Nothing
[[ "01" == ?([+-])+([0-9]).+([0-9.]) ]] && echo OK # Nothing
[[ "0.1" == ?([+-])+([0-9]).+([0-9.]) ]] && echo OK # OK
[[ "0.3.2" == ?([+-])+([0-9]).+([0-9.]) ]] && echo OK # OK
[[ "0.1.141" == ?([+-])+([0-9]).+([0-9.]) ]] && echo OK # OK
[[ "10.1.141" == ?([+-])+([0-9]).+([0-9.]) ]] && echo OK # OK
To clarify this question, the code should only accept numbers
separated with dots, like software program versioning.
[[ "0" == +([0-9]).+([0-9.]) ]] && echo OK # Nothing
[[ "01" == +([0-9]).+([0-9.]) ]] && echo OK # Nothing
[[ "0.1" == +([0-9]).+([0-9.]) ]] && echo OK # OK
[[ "0.3.2" == +([0-9]).+([0-9.]) ]] && echo OK # OK
[[ "0.1.141" == +([0-9]).+([0-9.]) ]] && echo OK # OK
[[ "10.1.141" == +([0-9]).+([0-9.]) ]] && echo OK # OK

Related

ksh if loop vs [[ ]] && { cmd1 ; } || { cmd2 ; }

I am working on a shell script and following syntax works fine:
if [[ 1 -eq 1 ]] ; then
[[ 2 -eq 1 ]]
else
echo hi
fi
Debug run :
+ [[ 1 -eq 1 ]]
+ [[ 2 -eq 1 ]]
If i shrink the statement it jumps to the else condition:
**[[ 1 -eq 1 ]] && { [[ 2 -eq 1 ]] ; } || echo hi**
Debug run:
+ [[ 1 -eq 1 ]]
+ [[ 2 -eq 1 ]]
+ echo hi
hi
any ideas what is missing?
Thanks much.
Sam
You could say the following:
[[ 1 -eq 1 ]] && { [[ 2 -eq 1 ]] ; true ; } || echo hi
if the first test passes, you go into the {...} block and once you run, what you wanted to run in there, by ending with true you do not continue past || here standing in for your else clause.
The problem is. [[ 2 -eq 1 ]] returned false and hence you get to your echo hi beyond ||.
All that said, you may see it looks a bit ugly and in this case (esp. as multiple conditions are involved which may impact how your pipeline gets evaluated). Well, I would recommend not saving on few newlines and for sake of obvious and readable code use the longer form.

Bash regex comparison issue

I have the following function
checkFormat()
{
local funcUserName=$1
if [[ "$funcUserName" != [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9] ]];then
echo "1"
else
echo "0"
fi
}
if [[ $string != [a-zA-Z0-9]* ]]
Only returns true if the first character is not [a-zA-Z0-9]
if [[ $string != [a-zA-Z0-9]{5} ]]
Never returns true.
if [[ $string != [a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9] ]]
Returns as I want it to.
Why is this?
The code is to check that a username is 5 characters long and alphanumeric i.e.
Joe12 or 12345 but not %$134.
bash version 4.2.37
I suggest to replace
if [[ $string != [a-zA-Z0-9]{5} ]]
by
if [[ ! $string =~ ^[a-zA-Z0-9]{5}*$ ]]
to match a regex.

Unix grep using Regex

In Unix, I need an input validation which use grep:
echo $INPUT| grep -E -q '^foo1foo2foo3' || echo "no"
What I really need is if input doesn't match at least one of these values: foo1 foo2 or foo3, exit the program.
Source: syntax is taken from Validating parameters to a Bash script
You need to use alternation:
echo "$INPUT" | grep -Eq 'foo1|foo2|foo3' || echo "no"
Do you really need grep? If you're scripting in bash:
[[ $INPUT == #(foo1|foo2|foo3) ]] || echo "no"
or
[[ $INPUT == foo[123] ]] || echo "no"
If you want "$INPUT contains one of those patterns
[[ $INPUT == *#(foo1|foo2|foo3)* ]] || echo "no"
Does this solve your problem:
echo $INPUT | grep -E 'foo1|foo2|foo3' || echo "no"
?

How to match regular expressions with an if statement

I am trying to perform a simple comparison within an if statement
basically it is taking the input from a user and then checking to verify that it is a proper entry.
This specific script is checking serial numbers.
read -p "enter in you serial number: serial_number
if [[ $serial_number == FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
then echo -e "validation passed"
else echo -e "validation failed"
fi
However if I enter FOO123-ABCD, I get validation failed.
The only way I have been able to get it to work is much uglier
if $serial_number == [A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]-[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9] ]]
Is there something I am doing wrong with the curly braces or is there some switch I have to use in order to compare extended expressions?
So far I have tried:
[[ "$serial_number" == FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "$serial_number" == "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
[[ "${serial_number}" == FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "${serial_number}" == "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
[[ "$serial_number" =~ FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "$serial_number" =~ "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
[[ "${serial_number}" =~ FOO[A-Z0-9]{3}-[A-Z0-9]{4} ]]
[[ "${serial_number}" =~ "FOO[A-Z0-9]{3}-[A-Z0-9]{4}" ]]
This is working fine for me:
read -p "enter in you serial number:" serial_number
echo ">>$serial_number<<"
if [[ "$serial_number" =~ ^FOO[A-Z0-9]{3}-[A-Z0-9]{4}$ ]]; then
echo -e "validation passed"
else
echo -e "validation failed"
fi
Note you need the ^ and $. Else it's checking for an occurrence anywhere in the string (like egrep).

Extended Regular Expression in UNIX

I don't mean that this question for UNIX only, but I work on Solaris, and I didn't try it on any other OS.
I confused between the extended regular expression:
first:
[[ "str" == ?(str|STR) ]] && echo "matched"
this work correct, but when:
[[ "str str" == ?(str|STR)(.*) ]] && echo "matched"
it doesn't work, does it mean that I can only compare one pattern.
Second:
[[ "str" =~ ?(str|STR) ]] && echo "matched"
I can't use this form here why?, but when:
[[ "str" == (str|STR)? ]] && echo "matched"
it works correctly.
It looks like you are trying to combine
extended globs
with
extended regular expressions. I would say this is A Bad Thing.
$ set '(str|STR)'
$ [[ 'str' =~ $1 ]] && echo matches
matches
$ [[ 'str str' =~ $1 ]] && echo matches
matches