LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices

Reply
 
LinkBack Search this Thread
Old 03-27-2009, 01:16 PM   #1
anonguy9
LQ Newbie
 
Registered: Mar 2009
Posts: 25

Rep: Reputation: 16
bash: checking if a variable is a number (need regular expression help)


UPDATE: I designed a bunch of regular expressions which seems to work extraordinarily well. See post #7


----


First, doesn't bash already include a feature to do this?

I do want to achieve this in pure bash, for portability and learning.


I've spent a few hours working on this. I did some hunting and I built a few working examples. I'll paste them all here for completeness, but I did develop a very nice bash-only solution. But to make things just right, I need some help with the regular expression for it.

I've spent a few hours (just today) doing research and trying examples out. Regular expressions make my soul bleed.

There are many other documents out there, none of which seem to help me in my circumstance with my brain, here are some links I've been using:

- tldp - The comically-titled "Bash Guide for Beginners"
- faqs.org
- xytrax.com


Some testing code:

Code:
test() {
  check() {
    isnumber "$1"
    if [ $? -eq 0 ] &>/dev/null ; then
      printf "yes"
    else
      printf "no"
    fi
    echo " - $1"
  }

  echo ""
  echo "Not numbers: "
  check "a"
  check "abcdefghijklmnopqrstuvwxyz"
  check "a."
  check "-a"
  check "+a"
  check "a1"
  check "a1.0"
  check "++1"
  check "--1"
  check "1--"
  check "1++"
  check "..1"
  check "1.."
  check "1..0"
  check "1.1.1"
  check "-"
  check "+"
  check "."
  check "--"
  check "++"
  check ".."

  echo ""
  echo "Numbers: "
  check "11"
  check "1"
  check "1."
  check ".1"
  check "-1"
  check "+1"
  check "+.1"
  check "-.1"
  check "1.1"
  check "-1.1"
  check "+1.1"
}

My regular expression:

Code:
regexp='^[-|+|0-9|.][.0-9]*$'

With grep:

Code:
isnumber() {
  if echo $1 | grep '\($regexp\)' &> /dev/null ; then
    return 0
  else
    return 1
  fi
}
With sed:

Code:
isnumber() {
  check=`echo $1 | sed "s/\($regexp\)//"`
  if [ -z ${check} ] ; then
    return 0
  else
    return 1
  fi
}

Checking if math can be done on it:

Code:
isnumber() {
  if expr $1 + 1 &> /dev/null ; then
    echo "yes"
  else
    echo "no"
  fi
}

Leveraging bash typeset (thanks unSpawn):

Code:
isnumber() {
  typeset -i chkvar
  let "foo=$1" 2>/dev/null
}

Bash regular expression (the best method so far):

Code:
isnumber() {
  if expr match "$1" "\($regexp\)" &> /dev/null ; then
    return 0
  else
    return 1
  fi
}

To test:

- Open a terminal
- Paste in the first block of code with test()
- Paste in the method you want to try
- Paste in your regexp= and type "test"

Or if you want to play around with the regular expression, I do this:

Code:
regexp='^[-|+|0-9|.][.0-9]*$';test
Then I can scroll up in my terminal and check, and then press up and edit my previous command to fiddle and fiddle all I like.


----

Questions:

- Doesn't bash have a way to easily tell if a string is a valid number?

- Can bash do math on numbers with a decimal in them?

- Can bash do math on negative numbers?

- Has someone out there written a decent function which can do this?

- Are there any other fringe test cases I should try? (Also, "+" as an input seems to act strangely.. but I haven't tracked that down)

- Could I have a suggestion on other regular expressions to try, or maybe a bit of a pointer on what I'm doing wrong?

- Is there better online documentation on regular expressions which I should know about?

- Are there any regular expression tools which I should check out? (There was one I used in kate, but I have issues getting kate running again and don't want to troubleshoot right now.)

- Are there any tools which could help me build regular expressions in the manner I'm suggesting? (big list of things to match against, expected failures and successes)


----


As an aside, some thoughts..

The fundamental difficulty I (and probably every regular human) seems to be in the way regex expects to be used.

I simply can't comprehend the language which regular expressions talks in. It's something like:

Match only
- stuff like this
- stuff and like that


What I'm expecting to do with regular expressions is more like:

Match everything like like this kind of stuff
- except this kind of stuff
- except that kind of stuff

That's how humans think. We also start counting with one, but that's another story.

Last edited by anonguy9; 03-30-2009 at 11:43 AM. Reason: Added new possibility.
 
Old 03-27-2009, 02:23 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 26,539
Blog Entries: 51

Rep: Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604Reputation: 2604
Quote:
Originally Posted by anonguy9 View Post
Doesn't bash have a way to easily tell if a string is a valid number?
Something like
Code:
typeset -i chkvar; str="$1"; let "foo=$str" 2>/dev/null
was posted before on LQ.
 
Old 03-27-2009, 04:17 PM   #3
anonguy9
LQ Newbie
 
Registered: Mar 2009
Posts: 25

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by unSpawn View Post
typeset -i chkvar; str="$1"; let "foo=$str" 2>/dev/null
Searching for typeset and chkvar, I see this thread.

I haven't worked with typeset before, so I didn't know to search for that one.

Edit:

I tested this out, and it's not bad, but it's no better than the math checking. This method won't understand strings which have a period in them, so very common examples like "1.1" and ".1" won't pass.

The regular expression method is still the best so far.

Last edited by anonguy9; 03-27-2009 at 04:32 PM.
 
Old 03-27-2009, 04:32 PM   #4
anonguy9
LQ Newbie
 
Registered: Mar 2009
Posts: 25

Original Poster
Rep: Reputation: 16
duplicate post removed

Last edited by anonguy9; 03-27-2009 at 04:32 PM. Reason: removing duplicate - oops
 
Old 03-27-2009, 05:58 PM   #5
synss
Member
 
Registered: Jul 2007
Location: Germany
Distribution: Arch Linux, Mac OS X
Posts: 131

Rep: Reputation: 22
Quote:
Originally Posted by anonguy9 View Post
With grep:

Code:
isnumber() {
  if echo $1 | grep '\($regexp\)' &> /dev/null ; then
    return 0
  else
    return 1
  fi
}
What about grep -q? You could then remove all of your if then else return "thingy". And bash can deal with negative numbers, try for yourself
Code:
bash
echo $((-1-1))
I did not read everything from your post.

Last edited by synss; 03-27-2009 at 06:00 PM.
 
Old 03-28-2009, 12:51 AM   #6
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,093

Rep: Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995Reputation: 1995
1. here's a regex method in pure bash (min version 3.x I believe)
http://www.tldp.org/LDP/abs/html/bas...#REGEXMATCHREF
2. bash can only do integer arithmetic natively, use other tools eg bc for floating point/'decimal'.
Take this into consideration when trying to decide what constitutes a number ...
 
Old 03-29-2009, 02:37 AM   #7
anonguy9
LQ Newbie
 
Registered: Mar 2009
Posts: 25

Original Poster
Rep: Reputation: 16
Talking New hotness

posting it on my blog instead

Last edited by anonguy9; 05-02-2009 at 02:15 AM. Reason: posting it on my blog instead
 
  


Reply

Tags
bash, check, checking, expression, grep, let, link, number, regex, regexp, regular, typeset, typing, url, variable


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Bash: Counting the number of character occurences in a variable basildon Linux - Newbie 3 09-22-2008 10:11 AM
regular expression (.*?) uttam_h Programming 6 05-30-2008 05:45 PM
bash scripting : printing variable with the number within $i amdGTintel Programming 2 01-18-2007 01:30 AM
Regular expression to match "^" then a number? PsychosisNode Linux - Newbie 1 01-14-2007 09:26 AM
Need help with Regular Expression subaruwrx Linux - Newbie 6 09-04-2004 07:48 PM


All times are GMT -5. The time now is 10:42 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration