Forum Moderators: bakedjake

Message Too Old, No Replies

Test for variable holding digit

Incredibly simple Bash script problem is too hard for me

         

Bernard Marx

5:46 pm on Aug 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Here's my little script. It takes its parameters, adds them up, and spits out the sum.


declare -i sum=0

for arg in "$@"; do
sum=sum+arg
done

echo $sum

Now I need to test, in the loop, if arg is a valid integer.
This must be child's play, surely?

MattyMoose

6:51 pm on Aug 19, 2004 (gmt 0)

10+ Year Member



How about:


declare -i sum=0

for arg in "$@"; do
if [ $arg -ge 0 ]; then
sum=sum+arg
fi
done

echo $sum

This only checks to see if the value is greater than 0, so if you're expecting or allow negatives in there, change 0 to be an insanely high negative number.

Bernard Marx

7:47 pm on Aug 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the reply, Moose.

A couple of problems there:
1. -ge expects an integer argument, and causes an error if it doesn't get one.
2. That would rule out -ve integers as arguments.

I'm playing with this case structure:


case $xx in
[0-9]) echo integer;;
*) echo "not integer";;
esac

..but I dont know how to match {any amount of [0-9], but nothing else }
..and I don't know how to handle the minus sign either!

MattyMoose

7:56 pm on Aug 19, 2004 (gmt 0)

10+ Year Member



Ya, I know it returns an error, but it doesn't break from the program... Just complains, thought you might be able to /dev/null that or something, but the case statement might be better.

How about:

case $xx in
[a-z]) echo Not integer
;;
*) echo "integer";;
esac

Where it says a-z, put in everything that's not an int, and the * will catch everything else (that's hopefully an int), of any size...

Or:

case $xx in
[0-9,-]) echo integer;;
[0-9,-][0-9]) echo integer;;
[0-9,-][0-9][0-9]) echo integer;;
[0-9,-][0-9][0-9][0-9]) echo integer;;
[0-9,-][0-9][0-9][0-9][0-9]) echo integer;;

*) echo "not integer";;
esac

ad nauseam.

MattyMoose

8:06 pm on Aug 19, 2004 (gmt 0)

10+ Year Member



This one works:


#!/usr/local/bin/bash
x=$1
case $x in
*[!0-9]*)
echo It is not an integer
;;
*)
echo It is an integer
;;
esac

Bernard Marx

8:44 pm on Aug 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks lots. That's working (except for -ve ints)

A couple (or more) queries:

1. When I was using the case structure [0-9]* was matching strings like 123abc, as [0-9].* is supposed to.
2. Does this explain the first * in (*[0-9]*) ..?
(All the refs I find say: [0-9]* matches any number {there's only 1 * there!})

3. Any idea how to match a minus sign too?

MattyMoose

9:07 pm on Aug 19, 2004 (gmt 0)

10+ Year Member



I'm no regex guru, but this may be a good place to start:

http://etext.lib.virginia.edu/helpsheets/regex.html [etext.lib.virginia.edu]

That will probably help you along.

But, here's one that I found:


#!/usr/local/bin/bash
x=$1
case $x in
*[!0-9+-]*¦?*[-+]*¦""¦-¦+) echo Is not an integer;;
*) echo Is an integer;;
esac

Fun!

-MM

Bernard Marx

9:29 pm on Aug 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Good man! That works a treat.

Now I'll just have to find out why. I can usually handle REs, but there seem to be so many slightly varying forms of pattern matching in Unix, I'm never sure where I am. I still can't find a reference to the extra *s. Still, I'll check out that link now.