how to make several comparisons in the bash by placing the condition and comparison points next to instead of the long queue ?
that something like this
before :
if [[ $var == "aaa" || $var == "bbb" || $var == "ccc" || $var == "ddd" ]];
then
echo "good";
fi
after (what I want):
if [[ $var==["aaa","bbb","ccc","ddd"] ]];
then
echo "good";
fi
With extended pattern matching:
shopt -s extglob
[[ $var = #(aaa|bbb|ccc|ddd) ]] && echo "good"
Try this using bash regex with the keywork =~:
if [[ $var =~ ^(aaa|bbb|ccc|ddd)$ ]];
then
echo "good";
fi
Edit :
As seen in comments, for real you need to compare int, not strings, so :
((var%3 == 0)) && echo "ok"
Using bash arithmetic
Related
I am novice to linux scripting. For the below example, i need to split the string as per "-" and store the output in an array as a separate element.
Later, i need to validate each element in an array if its an integer or alphanumeric. if its integer, i need to ignore that element and print only non-integer elements. The following script which i am trying is not giving expected output which should be like 'grub2-systemd-sleep-plugin'.
item = grub2-systemd-sleep-plugin-2.02-153.1
IFS='-'
read -rasplitIFS<<< "$item"
for word in "${splitIFS[#]}"; do echo $word; done
Taking a stab at this here...
Depends on how your numbers may be defined, but I believe you could use something like this to removing numbers from the output. I'm not sure if there is a more efficient way to achieve this
for word in ${splitIFS[#]}
do
c=$(echo $word | grep -c -E "^[0-9]+\.{0,}[0-9]+$")
[ $c -eq 0 ] && echo $word
done
If you're using bash, it will be faster if you use built-in tools rather than subshells.
line=grub2-systemd-sleep-plugin-2.02-153.1-foo-1
while [[ -n "$line" ]]
do if [[ "$line" =~ ^[0-9.]+- ]]
then line="${line#*-}"
elif [[ "$line" =~ ^[0-9.]+$ ]]
then break
elif [[ "$line" =~ ^([[:alnum:]]+)- ]]
then echo "${BASH_REMATCH[1]}";
line="${line#*-}"
elif [[ "$line" =~ ^([[:alnum:]]+)$ ]]
then echo "${BASH_REMATCH[1]}";
break
else echo "How did I get here?"
fi
done
or if you prefer,
shopt -s extglob
line=grub2-systemd-sleep-plugin-2.02-153.1-foo-1
while [[ -n "$line" ]]
do case "$line" in
+([0-9.])-*) line="${line#*-}" ;;
+([0-9.])) break ;;
+([[:alnum:]])-*) echo "${line%%-*}"
line="${line#*-}" ;;
+([[:alnum:]])) echo "$line"
break ;;
*) echo "How did I get here?" ;;
esac
done
I tried the following but without success
[root#OBAMA~]# bash
[root#OBAMA~]# a=HelloWorld
[root#OBAMA~]# [[ $a == [A-Za-z] ]] && echo "YES ITS STRING"
( the command not prints anything )
[root#OBAMA~]# [[ $a == [A-Z][a-z] ]] && echo "YES ITS STRING"
( the command not prints anything )
Change your command lke below.
$ [[ $a =~ [A-Za-z]+ ]] && echo "YES ITS STRING"
YES ITS STRING
Use =~ operator to test an input string against a regex.
Add + next to the character class, so that it would repeat the previous pattern or token one or more times. Here it's unnecessary.
Add anchors , in-order to do an exact string match. [[ $a =~ [A-Za-z] ]] && echo "YES ITS STRING" alone will print the string YES ITS STRING because the variable a contains atleast an alphabet.
$ a="HelloWorld"
$ [[ $a =~ ^[A-Za-z]+$ ]] && echo "YES ITS STRING"
YES ITS STRING
$ a="Hello World"
$ [[ $a =~ ^[A-Za-z]+$ ]] && echo "YES ITS STRING"
$
how do you define "a string"
[[ -n $a ]] && echo variable a is not empty
[[ $a == *[[:alpha:]]* ]] && echo variable a contains a letter
shopt -s extglob failglob
[[ $a == +([[:alpha:]]) ]] && echo variable a only has letters
Your glob expressions are not matching because your checking that your variable contains only 1 character or 2 characters.
I have a variable $projectName how can i check if it starts with this string 'testProject'
You can use this check in BASH:
[[ "$projectName" == "testProject"* ]]
You can for example use:
[[ "$projectName" =~ ^testProject ]] && echo "yes"
^
beginning of line
Test
$ var="hello"
$ [[ "$var" =~ ^he ]] && echo "yes" || echo "no"
yes
$ var="ahello"
$ [[ "$var" =~ ^he ]] && echo "yes" || echo "no"
no
I have a simple way to search for multiple substrings in a single string:
if [[ $string = *"string 1"* && $string = *"string 2"* && $string = *"string 3"* ]]
(here searching for string 1, string 2 and string 3 in string).
How can I simplify this, so that there is only one check?
I've tried:
if [[ $string = *"string 1"*"string 2"*"string 3"* ]]
and
if [[ $string = *"string 1*string 2*string 3"* ]]
Note: the three strings specified here will always be in this order, hence why I can simplify it.
In ksh93, you can use the & sub-pattern delimiter.
$ [[ abcdefg == #(*bcd*&*cde*&*efg*) ]]; echo $?
0
$ [[ abcdefg == #(*bcdz*&*cde*&*efg*) ]]; echo $?
1
Only ksh93 has this unfortunately. In mksh, zsh, and bash, with extended matching, the negation sub-pattern allows for this DeMorgan-like equivalence.
$ [[ abcdefg == !(!(*bcd*)|!(*cde*)|!(*efg*)) ]]; echo $?
0
$ [[ abcdefg == !(!(*bcdz*)|!(*cde*)|!(*efg*)) ]]; echo $?
1
To test for just one pattern, see this FAQ
This question already has answers here:
How to check if a string contains a substring in Bash
(29 answers)
Closed 9 years ago.
if[ xxx ]
how to expresss the string or file include '.'
I am new to study shell,thanks for any help
You can use the matching operator:
$ if [[ "abc.def" =~ \. ]]; then echo "yes"; else echo "no"; fi
yes
$ if [[ "abcdef" =~ \. ]]; then echo "yes"; else echo "no"; fi
no
This matches if the dot is the first or last (or only) character in the string. If you expect characters on both sides of the dot, you can do the following:
$ if [[ "ab.cdef" =~ .\.. ]]; then echo "yes"; else echo "no"; fi
yes
$ if [[ ".abcdef" =~ .\.. ]]; then echo "yes"; else echo "no"; fi
no
$ if [[ "abcdef." =~ .\.. ]]; then echo "yes"; else echo "no"; fi
no
You can also use pattern matching:
$ if [[ "ab.cdef" == *?.?* ]]; then echo "yes"; else echo "no"; fi
yes
$ if [[ ".abcdef" == *?.?* ]]; then echo "yes"; else echo "no"; fi
no
$ if [[ "abcdef." == *?.?* ]]; then echo "yes"; else echo "no"; fi
no
A good reference for both patterns and regexes is at Greg's Wiki
bash supports glob-style pattern matching:
if [[ "$file" = *?.?* ]]; then
...
fi
Note that this assumes a prefix as well - this also ensures that it will not match the . and .. directories.
If you want to check for a specific extension:
if [[ "$file" = *?.foo ]]; then
...
fi
echo "xxx.yyy" | grep -q '\.'
if [ $? = 0 ] ; then
# do stuff
fi
Or
echo "xxx.yyy" | grep -q '\.' && <one statement here>
#e.g.
echo "xxx.yyy" | grep -q '\.' && echo "got a dot"