This question already has answers here:
Bash If-statement to check If string is equal to one of several string literals [duplicate]
(2 answers)
Closed 6 years ago.
I want to check in my bash script, if a variable is equal to value 1 OR equal to value 2.
I don't want to use something like this, because the 'if true statements' are the same (some big echo texts), when the variable is equal to 1 or 2. I want to avoid data redundancy.
if [ $1 == 1 ] ; then echo number 1 ; else
if [ $1 == 2 ] ; then echo number 2 ; fi
More something like
if [ $1 == 1 OR 2 ] ; then echo number 1 or 2 ; fi
Since you are comparing integer values, use the bash arithmetic operator (()), as
(( $1 == 1 || $1 == 2 )) && echo "number 1 or 2"
For handling-strings using the regex operator in bash
test="dude"
if [[ "$test" =~ ^(dude|coolDude)$ ]]; then echo "Dude Anyway"; fi
# literally means match test against either of words separated by | as a whole
# and not allow for sub-string matches.
Probably the most easy to extend option is a case statement:
case $1 in
[12])
echo "number $1"
esac
The pattern [12] matches 1 or 2. For larger ranges you could use [1-5], or more complicated patterns like [1-9]|[1-9][0-9] to match any number from 1 to 99.
When you have multiple cases, you should separate each one with a ;;.
Related
how can i use a range of parameters in linux bash like 60-70 --> ($1 - $2)
case $1 in
$1-$2 )
echo "test"
shift;;
....) ....
Each case of a case statement is a pattern, but depending on the range, it can be tricky to specify a good pattern. 60-70, for instance, could be matched with
case $1 in
6[0-9] | 70) echo "test"
shift ;;
Essentially, you have to treat the numbers as digit strings, and match them as text. A range like 67-93, for instance, breaks down into the fairly unwieldy
6[7-9] | [78][0-9] | 9[0-3]
You can make a function for it.
When you have different ranges, make parameters like range(check, minimum, maximum).
Return 1 when check < minimimum, 0 when check inside boundaries
(or equal boundary) and 2 above:
range() {
if [ "$1" -lt "$2" ]; then
return 1
fi
if [ "$1" -gt "$3" ]; then
return 2
fi
return 0
}
When you want different returns for different ranges, change this function.
EDIT: Added quotes and made positive return values.
EDIT 2: changed function x into x()
I am trying to look a for some specific values (such as 1 or 4) from a text file using bash. If this value is found in the file, then I want to call a function and pass it the found value as an argument. If the values (1 or 4) are found under a certain column (such as Col3), then I would like to call another function.
The problem I am having is with the code not being able to recognize that the value found is from Col3 and calling a separate function. Its because I am skipping the first two lines so I have no way of tracking which value is under which column.
file.txt :
Name Col1 Col2 Col3
-----------------------
row1 1 4 1
row2 2 5 2
row3 3 6 3
Note that I am skipping the first two lines of the text file when searching the file. Also note that this code is a dummy version of what I have because I just need the general idea on how to approach this.
function retrieve {
if [[ "$1" == "1" ]]; then
var="one beer on the wall"
elif [[ "$1" == "4" ]]; then
var="four beers on the wall"
fi
}
function retrieve2 {
if [[ "$1" == "1" ]]; then
var="22 beers on the wall"
elif [[ "$1" == "4" ]]; then
var="44 beers on the wall"
fi
}
tail -n +3 $PWD/file.txt | while read -r ignored c1: do
echo "$c1"
done | while read -r value; do
if [[ //need to check if the value is under Col3 here// ]]; then
retrieve2 $value
else
retrieve1 $value
fi
echo $var
done
If I understand the problem correctly, we can read each line into an array, and the interate over it. If the field matches $val, then if we are in column $col we call retrieve2, if we are not in column $col we call retrieve1. Here is sketch of it.
#!/bin/bash
val=1
col=3
while read -ra cols
do
for ((i=1; i<${#cols[#]}; i++))
do
if (( cols[i] == val ))
then
if (( i == col ))
then
retrieve2
else
retrieve1
fi
fi
done
done < <(tail -n +3 file)
Note that this assumes that the values are numeric, if not, change the condition (( cols[i] == val )) to [[ ${cols[$i]} == "$val" ]]
However, since it is a bit cumbersome, it would probably be better to restructure your functions from bash to awk, and then do the whole processing in awk, if that makes sense.
This question already has answers here:
"Command not found" when attempting integer equality in bash
(3 answers)
Closed 8 years ago.
Output 1:
Enter your value: 12
./testscript.sh: line 4: 12: command not found
Your value is more than 10
Output 2:
Enter your value: 5
./testscript.sh: line 4: 12: command not found
Your value is more than 10
I need to know what is wrong. My Linux test is just tomorrow:(
#!/bin/bash
echo -n "Enter your value: "
read value
if [$value -lt 10]
then
echo "Your value is less than 10"
else
echo "Your value is more than 10"
fi
your if statement should be as below. A space before ']' and space after '['
if [ $value -lt 10 ]
EDIT
As per the comments
you can always add optional ; at the end of the line. The below script would work fine.
a=20;
if [ $a -gt 10 ];
then
echo "true";
else
echo "false";
fi
you need to put your condition in the [ condition ]. The below one does not work.
( condition )
It would say command not found. As '(' is not command. where as '[' is a command in order to check a condition
And the more appropriate way is to use [[ ]] over [ ] when in Bash since you can avoid word splitting and pathname expansion with it. Other conditions can be added as well:
if [[ ! $value =~ [0-9]+ ]]; then
echo "Invalid input."
elif [[ value -lt 10 ]]; then
echo "Your value is less than 10."
elif [[ value -eq 10 ]]; then
echo "Your value is 10."
else
echo "Your value is more than 10."
fi
To throw yet another option into the mix: bash has (( ... )) -- arithmetic conditions:
if (( $value < 10 )); then ...
http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs
One thing you can do in bash with arithmetic expressions is to drop the $.
if (( value < 10 )); then
This is documented a bit obscurely in Shell arithmetic: "Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax."
This may appeal to aficionados of C-like languages, but it's a bit out of step with the rest of the languages, and it doesn't apply to all variables (such as special paramaters ($#)
and array elements (${foo[3]})).
This question already has answers here:
What does the "$#" special parameter mean in Bash?
(2 answers)
Closed 8 years ago.
I have a script with this:
login {
# checking parameters -> if not ok print error and exit script
if [ $# -lt 2 ] || [ $1 == '' ] || [ $2 == '' ]; then
echo "Please check the needed options (username and password)"
echo ""
echo "For further Information see Section 13"
echo ""
echo "Press any key to exit"
read
exit
fi
} # /login
But I really dont know what the $# means on the third line.
The pound sign counts things.
If it's just $#, it's the number of positional parameters, like $1, $2, $3. (Not counting $0, mind you.)
If it's ${#var}, it's the number of characters in the expansion of the parameter. (String length)
If it's ${#var[#]}, it's the number of elements in the array. Since bash arrays are sparse, this can be different from the index of the last element plus one.
It's the number of arguments passed.
You can read it here, search for "Detecting command line arguments"
So I have a bash script that needs to take an arbitrary number of command line arguments and put them into a single string
Example of what the user would type in:
give <environment> <email> <any number of integers separated by spaces>
give testing stuff#things.com 1 2 3 4 5
I want to get all of the arguments from $3 to $# and concat them into a string.
My (probably awful) solution right now is
if [ $# -gt 3 ]
then
env="env="$1
email="email="$2
entList=""
for i in {3..$#}
do
if [ $i -eq 3 ]
then
entList=$3
shift
fi;
if [ $i -gt 3 ]
then
entList=$entList","$3
shift
fi;
done
fi;
I handle the case of having only three arguments a bit differently, and that one works fine.
Final value of $entList given the example give testing stuff#things.com 1 2 3 4 5 should be: 1,2,3,4,5
Right now when i run this i get the following Errors:
/usr/local/bin/ngive.sh: line 29: [: {3..5}: integer expression expected
/usr/local/bin/ngive.sh: line 34: [: {3..5}: integer expression expected
Lines 29 and 34 are:
line 29: if [ $i -eq 3 ]
line 34: if [ $i -gt 3 ]
Any help would be appreciated.
You're on the right track. Here's my suggestion:
if [ $# -ge 3 ]; then
env="$1"
email="$2"
entlist="$3"
while shift && [ -n "$3" ]; do
entlist="${entlist},$3"
done
echo "entlist=$entlist"
else
echo "Arguments: $*"
fi
Note that variables should always be put inside quotes. I'm not sure why you were setting env=env=$1, but I suspect that if you want to recycle that value later, you should do it programatically rather than by evaluating the variable as if it were a statement, in case that was your plan.
Skip first three arguments using a subarray:
all=( ${#} )
IFS=','
threeplus="${all[*]:3}"
The reason you're getting those error messages is that in:
for i in {3..$#}
The brace expansion is performed before the parameter expansion and so the following if statement is evaluated as:
if [ {3..$#} -eq 3 ]
which isn't valid.
Change your for statement to use the C style:
for ((i = 3; i <= $#; i++))
Use this style for integer comparison:
if (( $# > 3 ))
and
if (( i == 3 ))
and
if (( i > 3 ))
Put your parameters inside the quotes:
env="env=$1"
email="email=$2"
and
entList="$entList,$3"
although the quotes aren't necessary since word splitting isn't performed on the right side of an assignment and you're not assigning special characters such as whitespace, semicolons, pipes, etc.