This question already has an answer here:

I tried ls ?[0-9]* , this matches all files in current directory, but also expands any directories in my current directory as and matches the files in any sub directory. I want * to match only to current directory.

---- Program output --------------------------------



--- Expected output (text)---

Here d2 and d4 are directories, while others are files. I want them to be listed as d2 and d4 and not as d2: and d4:

marked as duplicate by muru, agc, jasonwryan, Sparhawk, Thomas Jun 18 '18 at 9:55

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


?[0-9]* only expands to names in the current directory that has a digit as their second character. ls, when getting a directory name, will obviously show the contents of that directory, which means that you will have to tell ls to not not do that.

You do this with ls -d:

ls -d -- ?[0-9]*


ls -d ./?[0-9]*

The -- and ./ will stop ls from interpreting the first character of the filename as an option if it starts with a dash.

If you are only interested in non-directories (and want to also weed out symbolic links to directories), then there are two immediately obvious ways of doing this.

  1. Use a shell loop, testing each name to see whether it's a directory or not and display the name if it isn't:

    for name in ?[0-9]*; do
        [ ! -d "$name" ] && printf '%s\n' "$name"

    To include files that start with a dot (hidden files), a shell may have a dotglob shell option that you may set before the loop (shopt -s dotglob in bash).

  2. Use find to look for non-directories (and weed out symbolic links to directories) in the current directory:

    find -L . -maxdepth 1 ! -type d -name '?[0-9]*'

    The -L option to find makes -type d refer to the target of any symbolic link (if the current pathname is a symbolic link).

  • Beware that on many systems and in some locales, [0-9] matches on much more than 0123456789. [[:digit:]] should be OK, use [0123456789] to be sure. – Stéphane Chazelas Jun 18 '18 at 5:49
  • Beware that in most Bourne-like shells, if there's no matching file, you may end up listing the ?[0-9]* file whose second character is not a digit. That's a misfeature introduced by the Bourne shell, fixed again in zsh, or in bash with the failglob option. – Stéphane Chazelas Jun 18 '18 at 5:51
  • Beware that ?[0-9]* would not expand .123 by default. find would find them though. – Stéphane Chazelas Jun 18 '18 at 5:53

You could pipe ls to egrep using a regex like so:

ls | egrep '.\d.*'
  • Can it be done by only using ls and wildcards ? – asdf Jun 18 '18 at 3:31
  • Sure you could do this: ls -d1 ?[0-9]* – Joe M Jun 18 '18 at 3:35
  • -1 Don't pipe ls, especially when ls -d is perfectly correct here. – Sparhawk Jun 18 '18 at 5:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.