Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I ensure a Bash string is alphanumeric, without an underscore?

Tags:

regex

grep

bash

sed

I'm adding a feature to an existing script that will allow the user to configure the hostname of a Linux system. The rules I'm enforcing are as follows:

  • Must be between 2 and 63 characters long
  • Must not start or end with a hyphen
  • Can only contain alphanumeric characters, and hyphens; all other characters are not allowed (including an underscore, which means I can't use the \W regex symbol)

I've solved the first two in the list, but I'm having trouble figuring out how to check if a bash string contains only letters, digits, and hyphens. I think I can do this with a regex, but I'm having trouble figuring out how (I've spent the past hour searching the web and reading man pages).

I'm open to using sed, grep, or any of the other standard tools, but not Perl or Python.

like image 212
Raam Dev Avatar asked Aug 04 '09 18:08

Raam Dev


People also ask

How do you make sure a string is only alphanumeric?

To check if given string contains only alphanumeric characters in Python, use String. isalnum() function. The function returns True if the string contains only alphanumeric characters and False if not.

Is underscore an alphanumeric character?

Alphanumeric characters by definition only comprise the letters A to Z and the digits 0 to 9. Spaces and underscores are usually considered punctuation characters, so no, they shouldn't be allowed.

What is the regex for underscore?

The _ (underscore) character in the regular expression means that the zone name must have an underscore immediately following the alphanumeric string matched by the preceding brackets. The . (period) matches any character (a wildcard).


2 Answers

Seems like this ought to do it:

^[a-zA-Z0-9][-a-zA-Z0-9]{0,61}[a-zA-Z0-9]$

Match any one alphanumeric character, then match up to 61 alphanumeric characters (including hyphens), then match any one alphanumeric character. The minimum string length is 2, the maximum is 63. It doesn't work with Unicode. If you need it to work with Unicode you'll need to add different character classes in place of a-zA-Z0-9 but the principle will be the same.

I believe the correct grep expression that will work with Unicode is:

^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$

Example Usage:


echo 123-abc-098-xyz | grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$'

result=$(grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$' <<< "this-will-work"); echo $result;

echo "***_this_will_not_match_***" | grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$'
like image 200
Welbog Avatar answered Sep 22 '22 14:09

Welbog


This is a bash script testing the first parameter whether it contains only alphanumerics or hyphens. It "pipes" the contents of $1 into grep:

#!/bin/bash
if grep '^[-0-9a-zA-Z]*$' <<<$1 ;
  then echo ok;
  else echo ko;
fi
like image 44
js. Avatar answered Sep 21 '22 14:09

js.