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

39,659

Solution 1

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:]]$'

Solution 2

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

Solution 3

you can do it with just bash

string="-sdfsf"
length=${#string}
if [ $length -lt 2 -o $length -gt 63 ] ;then
    echo "length invalid"
    exit
fi
case $string in
    -* ) echo "not ok : start with hyphen";exit ;;    
    *- ) echo "not ok : end with hyphen";exit ;;   
    *[^a-zA-Z0-9-]* ) echo "not ok : special character";exit;; 
esac

Solution 4

This is for the last one you need: sed -e 's/[^[:alnum:]|-]//g'

Share:
39,659
Raam Dev
Author by

Raam Dev

Updated on October 18, 2020

Comments

  • Raam Dev
    Raam Dev over 3 years

    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.

  • Alberto Zaccagni
    Alberto Zaccagni almost 15 years
    How do you use the second expression with grep? I'm looking for switches in the man page but with no success: I'm echoing a string that should match and nothing is output.
  • Welbog
    Welbog almost 15 years
    @Montecristo: grep -E or egrep
  • Alberto Zaccagni
    Alberto Zaccagni almost 15 years
    I tried it with this: echo 1asdas*_- | grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$', with no output (also without single quotes), lol I should ask a question I think... :P
  • Welbog
    Welbog almost 15 years
    @Montecristo: Your test string contains an asterisk and underscore and ends in a hyphen, none of which are permitted by the expression.
  • Alberto Zaccagni
    Alberto Zaccagni almost 15 years
    @Welbog: Thank you very much, I was totally missing the point of how to use that :P
  • Alston
    Alston over 8 years
    [:alnum:] doesn't include hyphens anymore.
  • Alston
    Alston over 8 years
    @Welbog May I ask that why the ^ symbol here [^[:alnum:]] represent negativeness(all non alpha and numeric chars)? But the ^ symbol here ^[[:alnum:]] represent starts with? And you mention that it works great with Unicode, do you have any reference? Thanks!
  • Alston
    Alston over 8 years
    Why ^ here represent negativeness instead of the first occurrence?
  • js.
    js. over 8 years
    It means "beginning of line", so every character between it and $ has to fit the pattern.
  • Alexander Mills
    Alexander Mills almost 6 years
    how the F do you use this
  • Welbog
    Welbog almost 6 years