I am trying to figure out a sane way to do a NOT clause in a case. The reason I am doing this is for transcoding when a case is met, aka if I hit an avi, there's no reason to turn it into an avi again, I can just move it out of the way (which is what the range at the base of my case should do). Anyway, I have some proto code that I wrote out that kind of gives the gist of what I am trying to do.
#!/bin/bash
for i in $(seq 1 3); do
echo "trying: $i"
case $i in
! 1) echo "1" ;; # echo 1 if we aren't 1
! 2) echo "2" ;; # echo 2 if we aren't 2
! 3) echo "3" ;; # echo 3 if we aren't 3
[1-3]*) echo "! $i" ;; # echo 1-3 if we are 1-3
esac
echo -e "\n"
done
expected results would be something like this
2 3 ! 1
1 3 ! 2
1 2 ! 3
Help is appreciated, thanks.
This is contrary to the design of case, which executes only the first match. If you want to execute on multiple matches (and in your design, something which is 3 would want to execute on both 1 and 2), then case is the wrong construct. Use multiple if blocks.
[[ $i = 1 ]] || echo "1"
[[ $i = 2 ]] || echo "2"
[[ $i = 3 ]] || echo "3"
[[ $i = [1-3]* ]] && echo "! $i"
Because case only executes the first match, it only makes sense to have a single "did-not-match" handler; this is what the *) fallthrough is for.
You can do this with the extglob extension.
$ shopt -s extglob
$ case foo in !(bar)) echo hi;; esac
hi
$ case foo in !(foo)) echo hi;; esac
$
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With