|
Home > Archive > Unix Shell > October 2004 > Testing for a particular parameter without looping
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Testing for a particular parameter without looping
|
|
| Timur Tabi 2004-10-04, 6:01 pm |
| I have a bash script that can get passed any number of different
parameters. At one point, I need to test if a particular parameter
has been passed. For example, the script could be called by "myscript
A B C", or it could be called by "myscript B C A". All I care about
is if "B" was passed.
I know I can do this with a loop, checking each parameter, but I was
wondering if it can be done without a loop, and preferably without
calling an external program (like awk). Any ideas?
| |
| Bit Twister 2004-10-04, 6:01 pm |
| On 4 Oct 2004 16:01:38 -0700, Timur Tabi wrote:
> I have a bash script that can get passed any number of different
> parameters. At one point, I need to test if a particular parameter
> has been passed. For example, the script could be called by "myscript
> A B C", or it could be called by "myscript B C A". All I care about
> is if "B" was passed.
>
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without
> calling an external program (like awk). Any ideas?
use _if_ statements
| |
|
| On Mon, 04 Oct 2004 16:01:38 -0700, Timur Tabi wrote:
> I have a bash script that can get passed any number of different
> parameters. At one point, I need to test if a particular parameter has
> been passed. For example, the script could be called by "myscript A B C",
> or it could be called by "myscript B C A". All I care about is if "B" was
> passed.
>
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without calling
> an external program (like awk). Any ideas?
Here is something that works if all parameters are single characters. Only
lightly tested -- may have bugs or make unwarranted assumptions!
=================================
#!/bin/bash
p="C" # variable p is set to parameter to look for
if [ "${*/$p/}" != "$*" ] ; then
echo "$p seen"
else
echo "$p not seen"
fi
=================================
| |
|
| On 2004-10-05, Bob <bob@dont.spam.me> wrote:
> Here is something that works if all parameters are single characters. Only
> lightly tested -- may have bugs or make unwarranted assumptions!
>
> =================================
> #!/bin/bash
>
> p="C" # variable p is set to parameter to look for
>
> if [ "${*/$p/}" != "$*" ] ; then
> echo "$p seen"
> else
> echo "$p not seen"
> fi
> =================================
For non-single characters, following the same idea, one could do:
p="theOption" # variable p is set to parameter to look for
if [ "${*/ $p /}" != "$*" ] ; then
echo "$p seen"
else
echo "$p not seen"
fi
--Seb
| |
| William Park 2004-10-04, 8:47 pm |
| Timur Tabi <nospam_timur@tabi.org> wrote:
> I have a bash script that can get passed any number of different
> parameters. At one point, I need to test if a particular parameter
> has been passed. For example, the script could be called by "myscript
> A B C", or it could be called by "myscript B C A". All I care about
> is if "B" was passed.
>
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without
> calling an external program (like awk). Any ideas?
Not in standard shell. With my patch to Bash shell,
${*|/B}
${@|/B}
will return positional parameters matching glob pattern 'B'.
Ref:
http://freshmeat.net/projects/bashdiff/
--
William Park <opengeometry@yahoo.ca>
Open Geometry Consulting, Toronto, Canada
| |
|
| On Tue, 05 Oct 2004 02:10:27 +0000, Seb wrote:
> On 2004-10-05, Bob <bob@dont.spam.me> wrote:
>
> For non-single characters, following the same idea, one could do:
>
> p="theOption" # variable p is set to parameter to look for
>
> if [ "${*/ $p /}" != "$*" ] ; then
> echo "$p seen"
> else
> echo "$p not seen"
> fi
>
> --Seb
Need to account for the optoin being first or last:
p="theOPtion"
opts=" $* "
if [ "${opts/ $p /}" != "$opts" ] ; then
<the rest as above>
Warning *totally* untested!
| |
| Ed Morton 2004-10-05, 3:01 am |
|
Timur Tabi wrote:
> I have a bash script that can get passed any number of different
> parameters. At one point, I need to test if a particular parameter
> has been passed. For example, the script could be called by "myscript
> A B C", or it could be called by "myscript B C A". All I care about
> is if "B" was passed.
>
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without
> calling an external program (like awk). Any ideas?
This will work if all your parameters are single-character and take no
arguments that might contain a "B":
case $* in
*B* ) echo "Eureka!" ;;
* ) echo "boo hoo..." ;;
esac
Regards,
Ed.
| |
| Stephane CHAZELAS 2004-10-05, 3:01 am |
| 2004-10-04, 22:15(-05), Ed Morton:
[...]
> case $* in
> *B* ) echo "Eureka!" ;;
> * ) echo "boo hoo..." ;;
> esac
[...]
That tests wether the concatenation (with spaces unless IFS was
modified) of the arguments contains "B", not wether there's a
"B" amongst the arguments
With zsh:
if (( $+argv[(r)B] )); then
echo "Eureka!"
else
echo "boo hoo..."
fi
There's no equivalent with bash, unless you're ready to suppose
that one particular character is not present in the arguments:
If it's "|":
IFS="|"
case "|$*|" in
*"|B|"*) echo yes;;
*) echo no;;
esac
--
Stephane
| |
| Bill Marcum 2004-10-05, 5:58 pm |
| On 4 Oct 2004 16:01:38 -0700, Timur Tabi
<nospam_timur@tabi.org> wrote:
> I have a bash script that can get passed any number of different
> parameters. At one point, I need to test if a particular parameter
> has been passed. For example, the script could be called by "myscript
> A B C", or it could be called by "myscript B C A". All I care about
> is if "B" was passed.
>
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without
> calling an external program (like awk). Any ideas?
case "$*" in
B *|* B *|* B) echo "script has B" ;;
esac
--
System Events
=-=-=-=-=-=-=
Sep 16 03:31:11 don kernel: lp0 on fire
| |
| Stephane CHAZELAS 2004-10-05, 5:58 pm |
| 2004-10-5, 07:15(-04), Bill Marcum:
[...]
> case "$*" in
> B *|* B *|* B) echo "script has B" ;;
> esac
~$ case "$*" in
case> B *|* B *|* B) echo "script has B" ;;
zsh: parse error near `*'
bash: syntax error near unexpected token `*'
esac> ksh: syntax error: `*' unexpected
esac> syntax error: `*' unexpected
Should be:
case "$*" in
B\ *|*\ B\ *|*\ B) echo "script has B" ;;
esac
But that works only for Bourne shell or with POSIX shells if IFS
is unset or starts with " ".
It's not reliable if arguments may contain spaces.
It can be shortened as:
case " $* " in
*" B "*) echo "script has B" ;;
esac
Actually, with bash and ksh93 (not zsh), you can do it as:
IFS=,
case ",${*//,/}," in
*,B,*) echo script has B;;
esac
Of course, that doesn't work if instead of "B", you have a
string with commas in it (but you could use an other character
then as first character of IFS).
I guess you shouldn't rely on that behavior as it's not the
behavior one would expect (at least by Bourne standard, $* is
supposed to be a normal parameter whose value is the
concatenation of the arguments with first character of IFS
inbetween, so that ${*//,/} shouldn't contain any ",").
--
Stephane
| |
| Ed Morton 2004-10-05, 5:58 pm |
|
Stephane CHAZELAS wrote:
> 2004-10-04, 22:15(-05), Ed Morton:
> [...]
>
>
> [...]
>
> That tests wether the concatenation (with spaces unless IFS was
> modified) of the arguments contains "B", not wether there's a
> "B" amongst the arguments
That's right. Hence the caveat I stated in the part you snipped.
Ed.
| |
| Stephane CHAZELAS 2004-10-05, 5:58 pm |
| 2004-10-05, 07:52(-05), Ed Morton:
[...]
>
> That's right. Hence the caveat I stated in the part you snipped.
[...]
Oops, sorry. I was reading too fast.
--
Stephane
| |
| Ed Morton 2004-10-05, 5:58 pm |
|
Stephane CHAZELAS wrote:
> 2004-10-05, 07:52(-05), Ed Morton:
> [...]
>
>
> [...]
>
> Oops, sorry. I was reading too fast.
>
No problem. By the way - hope you've settled in and are enjoying the
weather in sunny Scotland. I just got back from a 2-week trip there and
found the rain slightly warmer than I remembered ;-).
Ed.
| |
| Dana French 2004-10-05, 5:58 pm |
| nospam_timur@tabi.org (Timur Tabi) wrote in message news:<53bb806a.0410041501.d402b72@posting.google.com>...
> I have a bash script that can get passed any number of different
> parameters. At one point, I need to test if a particular parameter
> has been passed. For example, the script could be called by "myscript
> A B C", or it could be called by "myscript B C A". All I care about
> is if "B" was passed.
>
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without
> calling an external program (like awk). Any ideas?
A ksh93 solution (assumes command line options do NOT contain a colon):
IFS=":"
[[ "${*}" = @(B:*|*:B:*|*:B) ]] && print "B was passed"
--------------------------------------------------------
Dana French dfrench@mtxia.com
Mt Xia Technical Consulting Group http://www.mtxia.com
100% Spam Free Email http://www.ridmail.com
MicroEmacs http://uemacs.tripod.com
Korn Shell Web http://dfrench.tripod.com/kshweb.html
| |
| Stephen Riehm 2004-10-05, 5:58 pm |
| Timur Tabi wrote:
> I know I can do this with a loop, checking each parameter, but I was
> wondering if it can be done without a loop, and preferably without
> calling an external program (like awk). Any ideas?
Is there a reason for not using a loop?
I know that loops are slow etc., but in this case you're looping through
maybe 100 values, probably less than 10 - efficiency should not be a
concern. The solutions which run a regular expression over $* also
result in a loop, you just can't see it through all those cryptic
characters ;-) (don't lecture me, I know what they mean, it's called
"humor")
If you're looking for clarity, then I would suggest you loop through the
options once at the beginning of your script, and pull out the things
you're likely to need later on. Store them in simple variables. e.g.
$arg_a, $arg_b etc. Then, when you need to check if B was set, simply
refer to $arg_b. Another advantage of doing something like this is that
you can put your consistency checking (preventing conflicting
combinations of options, or automatically setting $verbose if you turned
on debugging etc).
Just a different slant on the problem.
Steve
|
|
|
|
|