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
精彩评论