开发者

Bash script that detects the type of argument it's given

I have a bash script that will take one argument: a product ID. The product ID can be in one of two formats: all numbers, or a mix of letters, numbers, and underscores. Depending on which type of ID is entered, the script will handle it in a slightly different way.

Right now, I'm using getopts with one flag for each subtype to distinguish between which type of product ID I'm going to be using 开发者_开发百科in the script. For example:

./myscript -n 1034596

or

./myscript -v AB_ABCD_12345

With a simplified version of the script looking like this:

#!/bin/bash
while getopts ":n:v:" opt; do
  case $opt in
    n)
      echo "This is a numbers only ID." >&2
      ;;
    v)
      echo "This is a letters, numbers, underscore ID" >&2
      ;;
  esac
done

Since the formats are static, that is, the first type of ID will never be anything but numbers, is there any way to automatically distinguish between the two types of IDs and handle them appropriately without the need for the -n or -v flag? So, I could just enter ./myscript 1034596 and the script will know that since the argument contains nothing but numbers it should process it a specific way.


#!/bin/bash

shopt -s extglob

case "$1" in
  +([0-9]) ) echo "This is a numbers only ID." >&2
    ;;
  +([a-zA-Z0-9_]) ) echo "This is a letters, numbers, underscore ID" >&2
    ;;
  *) echo "Unrecognized Product ID" >&2
esac


Pure Bash 3.X

#!/bin/bash
if [[ "$1" =~ ^[0-9]+$ ]]; then
  echo "This is a numbers only ID." >&2
else
  echo "This is a letters, numbers, underscore ID" >&2
fi

Output

$ ./argtype.sh 1034596
This is a numbers only ID.
$ ./argtype.sh AB_ABCD_12345
This is a letters, numbers, underscore ID


Try this code:

#!/bin/bash
if [ $1 -eq $1 2> /dev/null ]; then
    echo number
else
    echo not number
fi

The output on your given input is:

brent@battlecruiser:~$ ./test2 1034596
number
brent@battlecruiser:~$ ./test2 AB_ABCD_12345
not number


There is a perhaps slightly more readable way with bash, but this can be done perfectly reasonably in pure portable sh.

unset LC_COLLATE
case $1 in
  *[!0-9A-Z_a-z]*) echo 1>&2 "Invalid product ID"; exit 2;;
  *[!0-9]*) echo "alphanumeric product ID";;
  *) echo "numeric product ID";;
esac


Take a look at accepted the answer to this question. Around line 8 is a regex technique that you can adapt.


#!/bin/sh

arg="$1"
output=`echo "$1" | grep -o "[0-9]\+"`
if [ "$output" == "$arg" ]; then
  echo "Numbers only"
else
  echo "Mixed"
fi


In Bash 3.2 or greater:

pattern1='^[0-9]+$'
pattern2='^[0-9a-zA-Z_]+$'
if [[ $1 =~ $pattern1 ]]
then
    echo "argument consists only of digits and is validated"
else
    echo "argument contains other characters"
    if [[ $1 =~ $pattern2 ]]
    then
        echo "argument is validated"
    else
        echo "argument contains invalid characters"
    fi
 fi


You could use grep to validate if the string passed in is a number:

#!/bin/bash
echo $1 | grep -q "^[0-9]*$"
if [ $? ]; then
    echo "Number"
else
    echo "Not a number"
fi

With comments updates:

#!/bin/bash

if grep -q "^[0-9]*$" <<< "$1"; then
    echo "Number"
else
    echo "Not a number"
fi
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜