Bash – Why does [a-z] asterisk match numbers

bashregular expressionwildcards

I have 3 directories at current path.

$ls
a_0db_data  a_clean_0db_data  a_clean_data
$ls a_*_data
a_0db_data:

a_clean_0db_data:

a_clean_data:

$ls a_[a-z]*_data
a_clean_0db_data:

a_clean_data:

I expected last ls command to match only a_clean_data. Why did it also match the one containing 0?

bash --version
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)

Best Answer

The [a-z] part isn't what matches the number; it's the *. You may be confusing shell globbing and regular expressions.

Tools like grep accept various flavours of regexes (basic by default, -E for extended, -P for Perl regex)

E.g. (-v inverts the match)

$ ls a_[a-z]*_data | grep -v "[0-9]"
a_clean_data

If you want to use a bash regex, here is an example on how to test if the variable $ref is an integer:

re='^[0-9]+$'
if ! [[ $ref =~ $re ]] ; then
  echo "error"
fi