Bash Shell Script Variable Value Check for integer and number range - bash

im trying to do a Number Check not including decimals as well as within range check but it is not working
example of accepted numbers: 1, 10, 100
not accepted numbers: 1.1, 10.1, 100.1
echo "Qty Sold: "
read sold
if [[ "$sold" =~ `^([0-9])$` && "$sold" -gt 0 && "$sold" -lt 999 ]] ;
then
echo "ok"
else
echo "Error, Qty Sold Must be Positive Integer";
fi

Remove the backticks which exists around your regex and use + after [0-9] to match one or more digits.
if [[ "$sold" =~ ^[0-9]+$ && "$sold" -gt 0 && "$sold" -lt 999 ]] ;
Example:
$ sold=12
$ if [[ "$sold" =~ ^[0-9]+$ && "$sold" -gt 0 && "$sold" -lt 999 ]] ; then echo 'Ok'; else echo 'NOT ok'; fi
Ok
$ sold=0
$ if [[ "$sold" =~ ^[0-9]+$ && "$sold" -gt 0 && "$sold" -lt 999 ]] ; then echo 'Ok'; else echo 'NOT ok'; fi
NOT ok
$ sold=1000
$ if [[ "$sold" =~ ^[0-9]+$ && "$sold" -gt 0 && "$sold" -lt 999 ]] ; then echo 'Ok'; else echo 'NOT ok'; fi
NOT ok

Without using regex:
((sold>0 && sold <999)) 2>/dev/null && echo "ok" || echo "Error, Qty Sold Must be Positive Integer"

The [[ syntax is a bit different from [ syntax. You do not need any delimiter around the regex in =~. So no / or backtick or apostrophe or ampersand is needed (only if regex contains a space. It can be escaped by backslash or add apostrophe or ampersand around the space or use [[:space:]] instead (which also includes TAB and some other whitespace characters)). What is more the ampersand also not needed around $sold (only in [[!). So the conditional part may be like this
if [[ $sold =~ ^[[:digit:]]{1,3}$ && $sold -gt 0 && $sold -lt 999 ]]; then echo ok
else echo "Error, Qty Sold Must be Positive Integer between 1 and 998";
fi
This checks if one, two or three digits are entered and it is not zero.

Related

Why is it saying integer expected? [duplicate]

This question already has answers here:
How do I test if a variable is a number in Bash?
(40 answers)
Closed 2 years ago.
#!/bin/bash
if [ "$1" == "" ] || [ "$2" == "" ] || [ "$3" == "" ]
then
echo This is empty or does not have all 3 parameters
exit
elif [ "$1" -lt 0 ]
then
echo This aint a number
exit
fi
Trying to run a script it is suppose first check if 3 positional parameters were entered,
secondly check if the input are numbers and then display the largest. I got the first if statement to work but when I input a string for the first parameter to test the elif statement an error that says integer expected.
you have to review the regex to check if string only contains digits, but you may try this:
#!/bin/bash
if [[ "$1" == "" ]] || [[ "$2" == "" ]] || [[ "$3" == "" ]]
then
echo "This is empty or does not have all 3 parameters"
exit
elif ! [[ "$1" =~ ^[0-9]+$ ]]
then
echo "This aint a number"
exit
fi
Note that [[ is actually a command/program that returns either 0 (true) or 1 (false). Any program that obeys the same logic (like all base utils, such as grep(1) or ping(1)) can be used as condition :
[[ -z STRING ]] #Empty string
[[ -n STRING ]] #Not empty string
[[ STRING == STRING ]] #Equal
[[ STRING != STRING ]] #Not Equal
[[ NUM -eq NUM ]] #Equal
[[ NUM -ne NUM ]] #Not equal
[[ NUM -lt NUM ]] #Less than
[[ NUM -le NUM ]] #Less than or equal
[[ NUM -gt NUM ]] #Greater than
[[ NUM -ge NUM ]] #Greater than or equal
[[ STRING =~ STRING ]] #Regexp
(( NUM < NUM )) #Numeric conditions
also to check if the string contains only digits/numerical cheracter
[[ "$1" =~ ^[0-9]+$ ]]
Please use a regex to check for number
#!/bin/bash
if [ $1 == "" ] || [ $2 == "" ] || [ $3 == "" ]
then
echo This is empty or does not have all 3 parameters
exit
elif ! [[ $1 =~ ^[0-9]+$ ]]
then
echo This aint a number
exit
fi

Checking if an integer is an element in array

I need to check if the value c exists in an integer array, I'm aware of how to approach this using for loops and if statements:
for c in {1..100};do
sequence=(2 4 6 8 10 12 14 16)
for value in "${sequence[#]}";do
if [[ $value -eq $c ]];then #If c exists in sequence
flag=1
break
fi
done
done
But I don't want this, I tried something similar to this:
[[ ${sequence[*]} =~ $c ]]
But it didn't give me the desired results, I think it works only with string arrays, not integers.
How could I approach this?
Converting my comment to answer so that solution is easy to find for future visitors.
You may use this grep + printf solution:
grep -qFx "$c" <(printf '%s\n' "${sequence[#]}") && echo "found" || echo "nope"
The problem with this method [[ ${sequence[*]} =~ $c ]] is that if $c is 1, than it'll match all instances with 1. Try this approach, make your sequence a regex like this
re=${sequence[*]}
re=${re// /|}
$ echo $re
2|4|6|8|10|12|14|16
Testing
c=1
$ [[ $c =~ $re ]] && echo ok || echo fail
fail
c=11
$ [[ $c =~ $re ]] && echo ok || echo fail
fail
c=12
$ [[ $c =~ $re ]] && echo ok || echo fail
ok

Shell Script - Case statement which finds exactly numbers (without +,-,/,*)

Briefly,
I have a variable ($num) which contains random number(max.18), I need a case statement in shell (because along with checking number, I also have some alphabet conditions) which should validate the user input with the variable (must be less than $num).
Ex:
case $input in
...
1) ... ;;
2) ... ;;
...
so, here if I have only two conditions than I can write code like this, but my variable $num contains random number, how can I write case conditions which satisfies my below requirements.
If user inputs numbers like (1/3,3*1,3-2,2+1) it should not validate as a number
If user inputs numbers like (0001 or 01 or 000001) it should not validate as a number
The case condition should execute only if user inputs number between 1-$num no other number formats or symbols should not allowed.
Ex:
case $input in
[nN*]) ...
[aA*]) ...
...
*) if echo "$input" | egrep '^\-?[0-9]+$'; then
typeset -LZ num
num="$input"
if [ "$input" != "$num" ]; then
echo "$input not a valid number"
fi
else
echo "please choose proper choice option"
fi
;;
This code works but I want a normal case condition which should satisfy my requirements like if we have two or three options we can simply write the code but what if we have random options (which may decrease or increase) how to write a case condition in that case.
Thanks!
If the usage of a case is not compulsory, try and use some regex validation to have more control on what is allowed and what not:
[[ $input =~ ^[1-9][0-9]*$ ]]
# ^ ^ ^ ^
# beginning | | end
# | any digit
# a digit from 1 to 9
This checks that the data in $input contains a number that does not start with 0.
$ r=001
$ [[ $r =~ ^[1-9][0-9]*$ ]] && echo "yes"
$
$ r=1
$ [[ $r =~ ^[1-9][0-9]*$ ]] && echo "yes"
yes
$ r="3+1"
$ [[ $r =~ ^[1-9][0-9]*$ ]] && echo "yes"
$
You can then check if the number is lower than the stored one:
[ $r -le $num ]
All together:
$ num=15
$ r=5
$ [[ $r =~ ^[1-9][0-9]*$ ]] && [ $r -le $num ] && echo "yes"
yes
$ r=19
$ [[ $r =~ ^[1-9][0-9]*$ ]] && [ $r -le $num ] && echo "yes"
$
$ r="3+1"
$ [[ $r =~ ^[1-9][0-9]*$ ]] && [ $r -le $num ] && echo "yes"
$
read -p "enter number" yournumber
re='^[0-9]+$'
if ! [[ $yournumber =~ $re ]] ; then
echo "error: Not a number" >&2; exit 1
fi
This is only code rest of the things you need to do it.

Bash if variable is an integer

I'm trying to write an if statement in bash that will exit if the variable supplied is not an integer. I will eventually be nesting this if statement within a while loop.
When I do run this I am getting an syntax error.
#!/bin/bash
if [ $f1 != ^[0-9]+$ ]
then
exit 1
fi
I have always like the integer test using the equality test construct:
[ $var -eq $var 2>/dev/null ] || exit 1
If var is not an integer, the equality fails due to the error generated. It is also POSIX compliant as it doesn't rely on character classes or the bash [[ construct.
You better negate the condition like this:
if [[ ! "$f1" =~ ^[0-9]+$ ]]; then
exit 1
fi
note the [[ and ]] syntax for the regular expressions, together with ! to negate it. Then, we use =~ for regexs.
Test
$ r=23a
$ [[ ! "$r" =~ ^[0-9]+$ ]] && echo "no digit" || echo "digit"
no digit
$ r=23
$ [[ ! "$r" =~ ^[0-9]+$ ]] && echo "no digit" || echo "digit"
digit

How do I validate decimal numbers?

Hi I'm working on an assignment and got stuck on this part, how do I validate decimal numbers/numbers in shell?
It can accept numbers but not decimal numbers. I want it to be able to accept both.
This is what I have so far
if echo $value | egrep '^[0-9]+$' >/dev/null 2>&1 ; then
echo "OK"
else
echo "There Is An Error"
echo "Please Try Again"
fi
Instead of using grep, you can use the bash to check expression:
#!/bin/bash
value=98.23
if [[ "$value" =~ ^[0-9]+(\.[0-9]+)?$ ]]
then
echo good
else
echo bad
fi
use this regex instead ^[0-9]*(\.[0-9]+)?$
Using bash's pattern matching:
shopt -s extglob
while read line; do
if [[ $line == ?([-+])+([0-9])?(.*([0-9])) ]] ||
[[ $line == ?(?([-+])*([0-9])).+([0-9]) ]]
then
echo "$line is a number"
else
echo "$line NOT a number"
fi
done << END
1
-1
a
1a
1.0
1.
.0
.
-.0
+
+0
+.0
END
outputs
1 is a number
-1 is a number
a NOT a number
1a NOT a number
1.0 is a number
1. is a number
.0 is a number
. NOT a number
-.0 is a number
+ NOT a number
+0 is a number
+.0 is a number
The patterns:
optional sign, followed by one or more digits, followed optionally by a dot and zero or more digits
optional sign, followed by zero or more digits, followed by a mandatory dot, followed by one or more digits.
How about this:
if [ ! -z $(echo "$value" | grep -o "^[1-9][0-9]*\.\?[0-9]*$") ]; then echo ok; fi
-z tests for an empty string. So the negation [ ! -z "" ] will be fulfilled if the given string starts with a matching pattern.
In standard shell ([[ is non-standard) test will do the validation for you.
if test "$value" -eq 0 -o "$value" -ne 0 2> /dev/null; then
: # $value is an integer
else
: # $value is not an integer
fi
Try this: It checks negative and decimal number also.
echo $value | egrep '^-[0-9]+$|^[0-9]+$|^[0-9].[0-9]+$|^-[0-9].[0-9]+$' > /dev/null
Works in both Bash 3.0 and 4.0.
isInteger() {
[[ $1 =~ ^[0-9]+$ ]];
}
isDecimal() {
[[ $1 =~ ^[0-9]+\.[0-9]+$ ]] && ! isInteger $1;
}
computer:~ # isDecimal 123 && echo true || echo false
false
computer:~ # isDecimal 12.34 && echo true || echo false
true
computer:~ # isDecimal 12.34a && echo true || echo false
false
computer:~ # isDecimal 0.0000001 && echo true || echo false
true
To check if number, simply test against both functions.

Resources