I'm trying to find a nice way of checking some text in order to set a variable. For instance to perform the logic: 'if the version string is 1.x then set a flag'. One way of doing this is:
versionFlag="0"
if grep -q "^1.*" versionfile; then
versionFlag="1"
fi
which is a little verbose. If I want to switch on multiple possibilities then that's easier:
case `grep "^1.*" versionfile` in
1.*)
echo "version 1"
;;
...
esac
But is there a nice one line way of just setting a flag to be true or false if some text matches a regexp or a wildcard?
versionFlag
is then set to 0. Any data in test matches,versionFlag
is set to the number of lines that match, soedit: this can be done even more simply
which will return a count of instances in the file
You can do something like this in bash 3.x (older versions don't support regex matching)
There isn't a ternary operator (e.g. ?:) in bash, so you are stuck with your if, then construct over multiple lines. You could use a different language that does have a ternary operator (PERL for example).
Mind you, a lot of folk discourage use of ternary operators as they aren't as easy to read in code - in other words, your comments end up longer than the multiple lines of code would have been.
I doubt there is a performance benefit of either method.
Actually, this construct:
[[ $version =~ ^1\.+ ]] && versionFlag=1
is easily extended to support the "no-match" case; just do this:
[[ $version =~ ^1\.+ ]] && versionFlag=1 || versionFlag=0
Incidentally, note the change from '*' to '+' in the regex. Using the star, the regex will still incorrectly match on a version value of "10". (The '*' modifier means "match zero or more occurrences", i.e., you still don't need to have a decimal point; the '+' modifier means "match one or more occurrences".) Making this change will, however, mean that "1" (i.e., a value without a decimal) will not match; this might or might not be a problem for your application.
There is also a way to do this without using the regex-match operator, if you don't have it; try this:
[[ ${version#1.} != ${version} ]] && versionFlag=1 || versionFlag=0
This is just a pattern-match, not a regex, so if you really need regex functionality, it won't work, but for simple stuff, it's great. (If you're not familiar with this form of parameter expansion, the "${version#1.}" construct expands to the value of "version", but with the post-'#' pattern removed from the beginning of the value if it was originally there. Example: If "version" has a value of "1.03", the result of "${version#1.}" is "03". Since this differs from the original value, the "!=" test succeeds.)