Bash – What does the (?) mean when using ls utility

bashshellwildcards

I am using the ls utility and my command looks like this:

$ ls x?[a-c]*

What is the output of such command? So far I understand (and I hope it's right) that it will list items that:

  • start with x
  • third letter is {a,b,c}
  • anything after third letter, does not matter, is included

My question is, what does the ? (question mark) represent? What condition is it?

Thank you in advance.

Best Answer

It is not an ls feature, it's a bash feature and it's described in the “Pattern Matching” section in bash(1):

The special pattern characters have the following meanings:

*

      Matches any string, including the null string.  When the globstar shell option is enabled, and * is used in a pathname expansion context, two adjacent *s used as a single pattern will match all files and zero or more directories and subdirectories.  If followed by a /, two adjacent *s will match only directories and subdirectories.
?
      Matches any single character.
[...]
      Matches any one of the enclosed characters.  A pair of characters separated by a hyphen denotes a range expression; any character that falls between those two characters, inclusive, using the current locale's collating sequence and character set, is matched.  If the first character following the [ is a ! or a ^ then any character not enclosed is matched.  The sorting order of characters in range expressions is determined by the current locale and the values of the LC_COLLATE or LC_ALL shell variables, if set.  To obtain the traditional interpretation of range expressions, where [a-d] is equivalent to [abcd], set value of the LC_ALL shell variable to C, or enable the globasciiranges shell option.  A - may be matched by including it as the first or last character in the set.  A ] may be matched by including it as the first character in the set.

Your understanding is also not entirely correct – ? means any single character, so the expression x?[a-c]* would match xQcFoo.bar, xmabc and x1abut also xabc - the point is that {a,b,c} may be also the second letter, not only the third. Output of ls x?[a-c]* command will be a list of files that match x?[a-c]* pattern. Or, if there are no such files, the shell won't substitute x?[a-c]* with anything, so ls will try to list the file literally named x?[a-c]*.

Related Question