1

So this is admittedly for university, but I can't find the answer anywhere, nor online, nor in the lecture notes.

I basically take a parameter, and have to search, if that is part of a longer string I have already stored:

if [ *$param* = $var ]
then
...

is the part in question. Now what is really weird for me, is that no matter if it says = or !=, the code nested under then never gets executed. I checked every other part of the code very thoroughly, and it all looks to be working fine.

Do you have any ideas what might cause this?

Bozont
  • 25
  • 3
  • Also, here a link to the [Advanced Bash-Scripting Guide](http://www.tldp.org/LDP/abs/abs-guide.pdf) which I've resorted many times in the past (and still do). – sal Nov 16 '18 at 17:37
  • 2
    @sal, please **don't** advise the ABS to others -- it's notorious as a source of bad-practice examples and outdated information (and has been for years -- see the timestamps next to the irc.freenode.org #bash factoid database entry in http://wooledge.org/~greybot/meta/abs; they're in epoch time, so #bash advice has been to skip the ABS since ~2008). The [bash-hackers' wiki](http://wiki.bash-hackers.org/) and the [BashGuide](http://mywiki.wooledge.org/BashGuide) are much better-maintained alternatives; there's also a lot of content overlap in the [BashFAQ](http://mywiki.wooledge.org/BashFAQ). – Charles Duffy Nov 16 '18 at 19:11
  • @CharlesDuffy Thanks for the additional pointers, I will check those out myself! – sal Nov 16 '18 at 22:00

3 Answers3

3

You just need to reverse the arguments. Inside [[ ... ]], =, ==, and != can perform pattern matching if the right-hand operand contains unescaped meta characters like * and ?, or a bracket expression [...].

if [[ $var == *"$param"* ]];   # check if $param is a substring of $var

Your code may or may not have performed pattern matching (depending on the contents of $var, but you were seeing if the string with the value of $param embedded in literal *s matched the value of $var.

For example, [[ foobar == *oba* ]] would succeed, as oba is a substring of foobar. [[ *oba* == foobar ]] would not, since *oba* and foobar are two distinct different strings. [[ *oba* == *oba ]] would also fail, since *oba* is not a string that ends with oba.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • 2
    Note that for strict matching, you should put the variable on the right in double-quotes (but not the wildcards!), like this: `[[ $var == *"$param"* ]]`. This forces any wildcard-type characters in the string to be matched literally. – Gordon Davisson Nov 16 '18 at 18:45
0

I would use grep

if echo $var | grep -q $param; then
  echo "found it!"
fi
Nick Ellis
  • 1,048
  • 11
  • 24
  • Quite buggy -- try this if your `param` contains spaces, or if your `var` contains the two-character string `-n`. (Also, spinning up a pipeline means you're `fork()`ing at least twice, and then using an `execve()` to replace off one of the forked-off subshells with an instance of `grep` for something the shell itself could do built-in). – Charles Duffy Nov 16 '18 at 19:15
0

Try this

if [[ $var =~ $param ]]; then
    echo "matches"
fi
Harald Nordgren
  • 11,693
  • 6
  • 41
  • 65
  • This is a regex, not a glob -- a very different syntax. – Charles Duffy Nov 16 '18 at 19:15
  • ...for example, if `param='.txt'`, `[[ $var =~ $param ]]` will match `atxt` even though `a` is not `.` (since `.` is a single-character wildcard in POSIX ERE regex syntax); whereas `[[ $var = *"$param"* ]]` will only match the precise substring. – Charles Duffy Nov 16 '18 at 23:47