Pages

Sunday, December 19, 2010

How to Validate Integer Input using Shell script


Method 1:


#!/bin/bash
# SCRIPT: validinteger.sh
# USAGE: validinteger.sh [ Input value to be validated ]
# PURPOSE: validate integer input, allow negative integers also
#
# \\\\ ////
# \\ - - //
# @ @
# ---oOOo-( )-oOOo---
#
# Using the $? exit status variable or integer comparison operators, a
# script may test if a parameter contains only digits, so it can be
# treated as an integer.
#
#####################################################################
# Arguments Checking #
#####################################################################

if [ $# -eq 0 ]
then
echo -n "Enter input to test: "
read Number
else
Number=$1
fi

# You can also use bellow one liner
#[ $# -eq 0 ] && { echo -n "Enter input:";read Number; } || Number=$1

#####################################################################
# Main Script Starts Here #
#####################################################################

# Check the input is an integer or not

if [ $Number -ne 0 -o $Number -eq 0 2>/dev/null ]
then

# An integer is either equal to 0 or not equal to 0.
# 2>/dev/null suppresses error message.

echo "Supplied Input $Number is an Integer"

else

echo "Supplied Input $Number is not an Integer."
fi

# You can compare number itself also

# if [ $Number -eq $Number 2> /dev/null ]
# then
# echo "Supplied Input $Number is an Integer"
# else
# echo "Supplied Input $Number is not an Integer."
# fi

OUTPUT:
# chmod 755 validinteger.sh
# ./validinteger.sh -12345
Supplied Input -12345 is an Integer
# ./validinteger.sh 12345A
Supplied Input 12345A is not an Integer.
# ./validinteger.sh
Enter input to test: 876549
Supplied Input 876549 is an Integer
# ./validinteger.sh
Enter input to test: -345k123
Supplied Input -345k123 is not an Integer.

Method 2 :



#!/bin/bash
# SCRIPT: validinteger2.sh
# USAGE: validinteger2.sh [ Input value to be validated ]
# PURPOSE: validate integer input, allow negative integers also
#
#
# \\\\ ////
# \\ - - //
# @ @
# ---oOOo-( )-oOOo---
#
# In this method if you want to allow negative integers, it gets a
# tiny bit more complicated. You must have basic knowledge of string
# manipulation methods.
#
#####################################################################
# Arguments Checking #
#####################################################################

if [ $# -eq 0 ]
then
echo -n "Enter input to test: "
read Number
else
Number=$1
fi

#####################################################################
# Main Script Starts Here #
#####################################################################

# Check first character is -

if [ "${Number:0:1}" = "-" ] #extract first character
then
RemNumber="${Number:1}" #extract except first char
else
RemNumber="$Number"
fi

# You can extract substring using bellow method also

#if [ "$(echo $Number|cut -c 1)" = "-" ]
#then
# RemNumber=$(echo $Number|cut -c 2-)
#else
# RemNumber="$Number"
#fi

if [ -z "$RemNumber" ]
then
echo "Supplied Input $Number is not an Integer"
else

NoDigits="$(echo $RemNumber | sed 's/[[:digit:]]//g')"

if [ -z "$NoDigits" ]
then
echo "Supplied Input $Number is an Integer"
else
echo "Supplied Input $Number is not an Integer."
fi
fi

OUTPUT:
# chmod 755 validinteger2.sh
# ./validinteger2.sh -987612
Supplied Input -987612 is an Integer
# ./validinteger2.sh -A987612
Supplied Input -A987612 is not an Integer.
# ./validinteger2.sh
Enter input to test: -123456789
Supplied Input -123456789 is an Integer
# ./validinteger2.sh
Enter input to test: A234K78
Supplied Input A234K78 is not an Integer.

Method 3:


#!/bin/bash
# SCRIPT: validinteger3.sh
# USAGE: validinteger3.sh [ Input value to be validated ]
# PURPOSE: validate integer input, allow negative integers also
#
# \\\\ ////
# \\ - - //
# @ @
# ---oOOo-( )-oOOo---
#
# In this method input value validated using ASCII value range of
# numbers (48 - 57).
# Sample script provided by Bond, Thank you Bond.
#
#####################################################################
# Arguments Checking #
#####################################################################

if [ $# -eq 0 ]
then
echo -n "Enter input to test: "
read Number
else
Number=$1
fi

# You can also use bellow one liner
#[ $# -eq 0 ] && { echo -n "Enter input:";read Number; } || Number=$1

#####################################################################
# Main Script Starts Here #
#####################################################################

# Check first character is - ?
# This is another method to extract substring using Substring Removal
# method.

if [ "${Number%${Number#?}}" = "-" ] #extract first char
then
RemNumber="${Number#?}" #extract all except first char
else
RemNumber="$Number"
fi

if [ -z "$RemNumber" ]
then
echo "Supplied Input $Number is not an Integer"
else

Length=${#RemNumber} # Counting length of the string

for ((i=0; i < Length; i++))
do

char=${RemNumber:$i:1} # Reads character one by one

code=`printf '%d' "'$char"` # Get ASCII value of char

# Compare code with ASCII value range of Intergers ( 48 - 57 )

if [ $code -lt 48 ] || [ $code -gt 57 ]
then
echo "Supplied Input $Number is not an Integer"
exit 1
fi

done

echo "Supplied Input $Number is an Integer."

fi

OUTPUT:
$ sh validinteger3.sh -1234
Supplied Input -1234 is an Integer.
$ sh validinteger3.sh -12-12
Supplied Input -12-12 is not an Integer
$ sh validinteger3.sh
Enter input to test: -
Supplied Input - is not an Integer
$ sh validinteger3.sh
Enter input to test: 123a456
Supplied Input 123a456 is not an Integer

12 comments:

  1. Hi Venu,

    Just another version to server the same purpose using comparison with ASCII chart:

    #!/bin/bash

    echo -e "\nScript to validate whether input is an Interger value of not"

    if [ $# -ne 1 ]
    then
    echo "Usage: $0 [Input Value to be validated]"
    exit
    fi

    str="$1"
    cnt=${#str} # Counting the length of string fetched

    for ((i=0; i < cnt; i++))
    do
    char=${str:$i:1} # Reading one character at a time from the input string

    code=`printf '%d' "'$char"` # Echo the ASCII value of character

    echo "code: " $code
    if [ $code -lt 48 ] || [ $code -gt 57 ] # Comparing the ASCII value range of Intergers ( 48 - 57 )
    then
    if [ $code -ne 45 ] # To accept the negative integer value as well
    then
    echo -e "Input is not an integer value\n"
    exit
    fi
    fi
    done

    echo -e "\nThe input is valid integer value\n"

    ReplyDelete
  2. Hi Bond,

    Your idea is good, but above script has a mistake.

    $ sh validintegernum.sh -12-12

    Script to validate whether input is an Integer value of not
    code: 45
    code: 49
    code: 50
    code: 45
    code: 49
    code: 50

    The input is valid integer value

    It accepts hyphen any where. I rectified it and posted as method 3.

    ReplyDelete
  3. From Method 1, how would I adapt

    if [ $Number -ne 0 -o $Number -eq 0 2>/dev/null ]

    so that it worked in a while loop so that I could keep prompting the user for a number until they entered one?

    ReplyDelete
  4. the ultimate numeric testing:

    #!/bin/bash

    n="$1"

    echo "Test numeric '$n' "
    if ((n)) 2>/dev/null; then
    n=$((n))
    echo "Yes: $n"
    else
    echo "No: $n"
    fi

    ReplyDelete
    Replies
    1. That accepts undesirable mathematical expressions as input too.

      E.g. try evaluating the string "1234 != 4321".

      Delete
  5. Samples:
    Test numeric 'foo'
    No: foo
    Test numeric '2'
    Yes: 2
    Test numeric '-7'
    Yes: -7
    Test numeric '+8'
    Yes: 8
    Test numeric '2**7'
    Yes: 128
    Test numeric '3+4+5'
    Yes: 12
    Test numeric '20%14'
    Yes: 6
    Test numeric '+'
    No: +
    Test numeric '-'
    No: -
    Test numeric '%'
    No: %

    ReplyDelete
  6. Maybe better use something like this:
    [[ $1 =~ ^-{0,1}[0-9]+$ ]] && echo 'It's a integer'
    or
    [[ $1 =~ ^-{0,1}[[:digit:]]+$ ]] && echo 'It's a integer'
    or
    [[ $1 =~ ^-{0,1}[[:xdigit:]]+$ ]] && echo 'It's a hex integer'

    ReplyDelete
  7. @Anonymous the 1st

    Great, but doesn't detect 0

    if ((${n}1)) 2>/dev/null

    works better to me :)

    ReplyDelete
    Replies
    1. Alex: Your logic too has bug. It doesnt detect null or space.
      for example n="" or n=" "

      Delete
  8. case $1 in
    *[!0-9]* | "") echo Not integer ;;
    *) echo Integer ;;
    esac

    ReplyDelete
  9. The simplest and most elegant solution is the section commented out in Method 1 above, but with the variable in quotes to take care of null value:

    # You can compare number (to) itself also

    if [ "$Number" -eq "$Number" 2> /dev/null ]
    then
    echo "Supplied Input $Number is an Integer"
    else
    echo "Supplied Input $Number is not an Integer."
    fi

    This takes care of all the possible variations (including "-12-12") and uses a test that is absolutely specific - "Can we carry out arithmetic operations on the variable or not?". If we can then it is a number, otherwise it isn't.

    ReplyDelete
  10. hi ,

    I have doubt in passing input values to the script.please some one help me?

    ReplyDelete