How to check in shell script if string variable contains a wildcard? - bash

I'm trying to check if string contains any wildcards.
Here is my failing attempt:
#!/bin/bash
WILDCARDS='* . ? ! ] ['
a="foo*bar"
for x in $REJECTED_WILDCARDS
do
if [[ "$a" == *"$x"* ]]
then
echo "It's there!";
fi
done
Any suggestions?

Slightly shorter and without a loop:
if [ "$a" != "${a//[\[\]|.? +*]/}" ] ; then
echo "wildcard found"
fi
The parameter substitution deletes all wildcards.
The strings are than no longer equal.

Set wildcards into a bash array, like so
wildcards=( '*' '.' '?' '|' ']' '[' )
Then
a="foo*bar"
for wildcard in "${wildcards[#]}";
do
if [[ $a == *"${wildcard}"* ]];
then
echo 'yes';
fi;
done

Related

Regarding Bash substring comparison

I try to test if a string starts with a certain prefix. But my script seems not work (I would expect the "if" branch will not get run). Can some Bash expert help to take a look? thanks!
Here is my code and test result:
$ cat testb.bash
#!/bin/bash
my_var="abcdefg";
if [[ "${my_var:0:5}"=="order" ]]; then
echo "value of my_var is ${my_var}.";
fi;
if [[ "${my_var:0:5}" -eq "order" ]]; then
echo "value of my_var is ${my_var}.";
fi;
if [ "${my_var:0:5}"="order" ]; then
echo "value of my_var is ${my_var}.";
fi;
$ bash -x testb.bash
+ my_var=abcdefg
+ [[ -n abcde==order ]]
+ echo 'value of my_var is abcdefg.'
value of my_var is abcdefg.
+ [[ abcde -eq order ]]
+ echo 'value of my_var is abcdefg.'
value of my_var is abcdefg.
+ '[' abcde=order ']'
+ echo 'value of my_var is abcdefg.'
value of my_var is abcdefg.
$
Whitespace is significant in this case. As you can see in the -x output, it understands the first condition as
[[ -n "${my_var:0:5}==order" ]]
Moreover, to test for a prefix, you can use a pattern:
[[ $my_var == order* ]]
To test the existence of substring, you can use either of these:
if [[ "$j" =~ string1 ]]; then
if [[ $j == *string1* ]]; then
In your particular case, you miss a space surounding ==, so instead of
if [[ "${my_var:0:5}"=="order" ]]; then
it should be
if [[ "${my_var:0:5}" == "order" ]]; then
^ ^
Finally, note that your condition was evaluated as true because it was evaluating if [ "string" ], which is true if string is not empty:
$ [ "a" ] && echo "yes"
yes
Test
$ cat a
#!/bin/bash
my_var="abcdefg";
if [[ "${my_var:0:5}" == "order" ]]; then
echo "value of my_var is ${my_var}."
elif [[ "${my_var:0:5}" == "abcde" ]]; then
echo "yeahaa"
else
echo "is not"
fi
$ ./a
yeahaa
Ok, i tested your code, you shoud such as the following code:
prefix="pre_order";
pre="pre_"
len=${#pre}
echo $len
if [[ "${prefix:0:len}" == "blahvlah" ]] ; then
echo "dddd"
fi;
Notes:
use == for string comparation
for ${} you should initilize a string variable before ${}
use len=${#pre} for lenght of string.
A POSIX-compliant way to test for a prefix is to attempt to remove the prefix, and compare the result to the original string. If the two are the same, the prefix is not present, the removal fails, and the expression expands to the original string.
prefix=foo
string=foobar
if [ "${string#$prefix}" = "$string" ]; then
printf "$string does not start with $prefix\n"
else
printf "$string starts with $prefix\n"
fi

How can you search for a char in a string in bash?

If I have a string var="root/Desktop", how can I determine whether var var contains a '/' character?
Bash can match against regular expressions with =~, try:
[[ $var =~ "/" ]] && echo "contains a slash"
The following would work
[[ "$var" = */* ]]
The portable solution that works in any Bourne-heritage shell and needs no expensive forks or pipes:
case $var in
(*/*) printf 'Has a slash.\n';;
(*) printf 'No slash.\n';;
esac
echo "${var1}" | grep '/' should work.

What is the difference between [ test ] and [[ test ]] in bash?

What is the difference between [ test ] and [[ test ]] in bash?
When is one more appropriate than the other and what does the ; at the end do?
if [[ -z $DIRECTORY ]];
then
DIRECTORY=html
fi
if [ ! -d "$DIRECTORY" ]; then
echo installation directory "'${DIRECTORY}'" does not exist
exit 1
fi
[[ is a bash keyword similar to (but more powerful than) the [ command. See http://mywiki.wooledge.org/BashFAQ/031 and http://mywiki.wooledge.org/BashGuide/TestsAndConditionals Unless you're writing for POSIX sh, we recommend [[.
We usually use single square brackets when we:
Check something with files and want to use patterns (e.g. asterisk): if [ -L $file ]; then
Check artithmetic expressions: if [ $a -lt $b ]; then
Check something with strings and want to use " " and treat special characters as normal (e.g. asterisk): if [ -z "$string" ]; then
We usually double square brackets when we:
Want to use pattern with string (e.g. asterisk): if [[ "$string1" == *[sS]tring* ]]; then
Block patterns in file names (e.g. asterisk) e.g. we search file named *.sh: if [[ -a *.sh ]]; then
Want to use operators && and ||: if [[ $a == 3 || $b == 4]]; then
Don't want to put strings in " "
[ is for shell, [[ is for bash.
For example :
Try [ $A -eq 1 ]: if $A is not set, it raise an error.
[[ $A -eq 1 ]] will works.

Bash, if's, reusing variables

if [[ $line == *"option 1"* ]]
then
CURRENT_OPTION=1
fi
if [[ $line == *"option 2"* ]]
then
CURRENT_OPTION=2
fi
if [[ $line =~ "What i want" ]]
then
if [[ $CURRENT_OPTION -eq 1 ]]
then
MEM1=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }')
elif [[ $CURRENT_OPTION -eq 2 ]]
then
MEM2=$(awk '/Used heap/ { gsub(/M/, " "); print $4 }')
fi
fi
Because CURRENT_OPTION is defined within an if, its value is not correct when checked in the third if. How do I pass it out so that it is?
Just declare CURRENT_OPTION at the top, something like:
declare -i CURRENT_OPTION=0
i to declare it as an int.
In all of your if statements you should enclose the variables in double quotes. If the variable is an empty string (or if the variable doesn't exist) then the if statement will not contain enough arguments and will throw an error.
Here is an example:
if [[ $var -eq 1 ]]
then
echo yes
else
echo no
fi
If var is uninitialised, bash will expand the statement to look like this:
if [[ -eq 1 ]]
then
echo yes
else
echo no
fi
There are not enough arguments to make the if statement valid here, and bash will throw an error:
bash: conditional binary operator expected
bash: syntax error near `1'
By wrapping the variable in quotes, this situation is avoided. This statement:
if [[ "$var" -eq 1 ]]
...
is expanded to:
if [[ "" -eq 1 ]]
...
and now the if statement has enough arguments (the first one being an empty string) to parse.

How do you compare a string containing an angle bracket '<' in bash?

The following bash script is giving me problems:
#!/bin/bash
if [[ $VAR -eq "<EMPTY>" ]]; then echo "Hello World!"; fi
Bash fails, complaining:
line 3: [[: <EMPTY>: syntax error: operand expected (error token is "<EMPTY>")
How can I test if the string contained in VAR is equivalent to the string "<EMPTY>"?
You are using the wrong operator. == is for strings, -eq is for numbers.
#!/bin/bash
if [[ $VAR == "<EMPTY>" ]]; then echo "Hello World!"; fi
Inside [[ ... ]], -eq has a different meaning: it is used to compare integers. You can use (( ... )) to compare integeres with normal operators, though. Use the following for strings:
[[ $VAR == "<EMPTY>" ]]

Resources