问题
I'm trying to write a Bash script that uses a variable as a pattern in a case statement. However I just cannot get it to work.
Case statement:
case "$1" in
$test)
echo "matched"
;;
*)
echo "didn't match"
;;
esac
I've tried this with assigning $test as aaa|bbb|ccc, (aaa|bbb|ccc), [aaa,bbb,ccc] and several other combinations. I also tried these as the pattern in the case statement: @($test), @($(echo $test)), $($test). Also no success.
EDIT
For clarity, I would like the variable to represent multiple patterns like this:
case "$1" in
aaa|bbb|ccc)
echo "matched"
;;
*)
echo "didn't match"
;;
esac
回答1:
You can use the extglob option:
#! /bin/bash
shopt -s extglob # enables pattern lists like +(...|...)
test='+(aaa|bbb|ccc)'
for x in aaa bbb ccc ddd ; do
echo -n "$x "
case "$x" in
$test) echo Matches.
;;
*) echo Does not match.
esac
done
回答2:
(Updated): here's something a bit different, but I hope it works for what you need it for:
#!/bin/bash
pattern1="aaa bbb ccc"
pattern2="hello world"
test=$(echo -e "$pattern1\n$pattern2" | grep -e $1)
case "$test" in
"$pattern1")
echo "matched - pattern1"
;;
"$pattern2")
echo "matched - pattern2"
;;
*)
echo "didn't match"
;;
esac
This makes use of grep to do the pattern matching for you, but still allows you to specify multiple pattern sets to be used in a case-statement structure.
For instance:
- If either
aaa,bbb, orcccis the first argument to the script, this will outputmatched - pattern1. - If either
helloorworldis the first argument, this will outputmatched - pattern2. - Otherwise it will output
didn't match.
回答3:
using eval also works:
eval 'case "$1" in
'$test')
echo "matched"
;;
*)
echo "did not match"
;;
esac'
来源:https://stackoverflow.com/questions/13254425/using-variable-as-case-pattern-in-bash