Reputation: 175
I am working on a bash shell script that tests a string and returns true for the following:
1) Has a minimum of 8 characters
2) Has at least one letter and one number
3) Has both a lowercase and uppercase letter
Through searching I did find how to get the number of characters in a string
srtLen=$(echo -m $str | wc -m)
And the if statement would be
if [ $strLen -ge 8 ]; then
#make bool var true
fi
But I cannot find how to test and return a boolean for if a string has a lower case letter, an uppercase letter and at least one number. I don't care if each test is separate and I imagine they would be in separate if statements which is why I have mentioned in the code above a boolean variable that will be set based on the conditions.
Upvotes: 2
Views: 263
Reputation: 6134
Here is a generic answer that will work with non-English locale and multi-byte UTF-8 characters.
Let us translate each of your requirements into bash
code:
$str
as a minimum of 8 characters: this can be done in several simple ways using bash builtins
[ "${#str}" -ge 8 ] && echo "str has a minimum of 8 characters"
Straightforward: we compare the length of $str
[[ "$str" == ????????* ]] && echo "str has a minimum of 8 characters"
$str
is checked against a pattern that matches at least 8 characters
[[ "$str" =~ .{8} ]] && echo "str has a minimum of 8 characters"
$str
is checked against a regular expression that matches an 8 character string
[ -n "${str#???????}" ] && echo "str has a minimum of 8 characters"
We check that $str
is not empty when the first 7 characters are removed (not obvious, should be avoided)
Has at least one digit:
[[ "$str" == *[[:digit:]]* ]] && echo "str has at least one digit"
$str
is checked against a pattern that matches a digit surrounded by any number of characters
[[ "$str" =~ [[:digit:]] ]] && echo "str has at least one digit"
$str
is checked against a regular expression that matches a single digit
[ -n "${str//[^[:digit:]]}" ] && echo "str has at least one digit"
We check that $str
is not empty when all non-digit characters are removed (not obvious, should be avoided)
Has at least one lowercase letter:
Same as for the digit, just replace [[:digit:]]
with [[:lower:]]
[[ "$str" == *[[:lower:]]* ]] && echo "str has at least one lowercase letter"
[[ "$str" =~ [[:lower:]] ]] && echo "str has at least one lowercase letter"
[ -n "${str//[^[:lower:]]}" ] && echo "str has at least one lowercase letter"
Has at least one uppercase letter:
Same as for the digit, just replace [[:digit:]]
with [[:upper:]]
[[ "$str" == *[[:upper:]]* ]] && echo "str has at least one uppercase letter"
[[ "$str" =~ [[:upper:]] ]] && echo "str has at least one uppercase letter"
[ -n "${str//[^[:upper:]]}" ] && echo "str has at least one uppercase letter"
You can of course combine the four conditions:
$ str='my ßtrÎñ9'
$ if [[ "${#str}" -ge 8 \
&& "$str" =~ [[:digit:]] \
&& "$str" =~ [[:lower:]] \
&& "$str" =~ [[:upper:]] \
]]; then
echo "str is a valid password"
else
echo "str is NOT a valid password"
fi
str is a valid password
Upvotes: 1
Reputation: 44354
This is for the English alphabet, if you need others then you need to mess with the locale and the variable LC_COLLATE
:
check_str()
{
str="$1"
# Has a minimum of 8 characters
if (( ${#str} > 7 )) &&
# Has at least one number
[[ "$str" = *[0-9]* ]] &&
# Has both a lowercase
[[ "$str" = *[a-z]* ]] &&
# and uppercase letter
[[ "$str" = *[A-Z]* ]]
then
return 0
else
return 1
fi
}
while :
do
read -p "Enter a string: " inp
if check_str "$inp"
then
echo "$str matches"
else
echo "$str does not match"
fi
done
Test run:
Enter a string: helloHHx
helloHHx does not match
Enter a string: helloH1x
helloH1x matches
Enter a string: 12345678
12345678 does not match
Enter a string: hello
hello does not match
Enter a string: now is The 4 time for all good men
now is The 4 time for all good men matches
Note that your criteria 2 and 3 overlap, for 2 we only need check if there is a number, presence of a letter is checked in 3.
Upvotes: 1