Reputation: 13
I have been driving myself mad on this. I just don't see why it doesn't work when bash variables are untyped. There should be no reason why not.
pat1=`. $NVM_DIR/nvm.sh && nvm ls | sed 's/\x1b\[[^\x1b]*m//g' | sed -e 's/[[:alpha:]|\/\)\-\>\(|[:space:]]//g' | sed 's/[-|\*]//g' | sed '/^$/d'`
pat2=`. $NVM_DIR/nvm.sh && nvm ls node | head -1 | awk '{print $2}' | cut -d v -f2`
these expand to:
~$ echo $pat1
9.5.0
9.5.0
9.5
9.5.0
4.8.7
6.12.3
8.9.4
~$ echo $pat2
9.5.0
So I want to check if the string found in $pat2
is in $pat1
string.
however it does not find it even though it clearly is in the pattern 3 times at least.
Checking for the pattern with a test like:
case "$pat1" in
*$pat2*)
echo 'match'
;;
*)
echo 'nomatch'
;;
esac
this gives:
~$ ./test.sh
nomatch
another test:
if [[ "$pat1" =~ "$pat2" ]]; then
echo 'match'
else
echo 'nomatch'
fi
again fails:
~$ ./test.sh
nomatch
Even tried some janky hacky method to no avail,
echo $pat1 | grep "$pat2" > /dev/null
if [ $? -eq 0 ]; then
echo "matched"
else
echo "nomatch"
fi
gives the result:
~$ ./test.sh
grep: brackets ([ ]) not balanced
nomatch
Been pulling my hair out today working on this. This must be due to the fact that both variables are command substitutions, it leads me to believe it is comparing the actual commands themselves rather than their output stored in the variables. So even though they echo the output, i think it may be comparing the string of the commands itself.
am I wrong? can anyone explain why this fails to match and if its possible with bash to compare the output of two commands in a string/sub-string type of comparison?
Upvotes: 1
Views: 303
Reputation: 781626
The grep
version is almost right, but you need to quote $pat1
, otherwise the newlines will be converted to spaces and everything will be on one line.
if echo "$pat1" | grep -F -q "$pat2"
then
echo "matched"
else
echo "nomatch"
fi
I've also added the -F
option to grep
so it will treat $pat2
as a fixed string rather than a regular expression.
Upvotes: 1
Reputation: 37298
I put your pat1
and pat2
values in files and didn't need to use |
anywhere.
#!/bin/bash
pat1=$(cat pat1|tr '\012' ' ')
pat2=$(<pat2)
#tst pat2="10.1"
echo "$pat1"
case "$pat1" in
*$pat2*)
echo 'match'
;;
*)
echo 'nomatch'
;;
esac
Produces
#dbg:pat2=9.5.0 pat1=9.5.0 9.5.0 9.5 9.5.0 4.8.7 6.12.3 8.9.4
match
If I un-comment the #tst pat2
line, the output is
#dbg:pat2=10.1 pat1=9.5.0 9.5.0 9.5 9.5.0 4.8.7 6.12.3 8.9.4
nomatch
Is there any chance your data was created for MS Windows? If so, check for Windows line endings with
head -10 file | cat -vet
if you see ^M$
at the end of each line, then run dos2unix file ....
(multiple file can be processed in one invocation, and the original file is overwritten with the same name.
IHTH nomatch
Upvotes: 1