9

To list all the files ending with 10 or 11 or 12 I have tried ls *[10-12] and ls *[10,11,12] but these are not working. I don't know why. Can anyone help me?

3
  • ls *[10,11,12] works well for me
    – UVV
    May 12, 2015 at 11:31
  • 4
    @UVV If you have a file ending on 20, 21 or 22 it will be listed.
    – jcbermu
    May 12, 2015 at 11:38
  • @UVV That would apply ls to all names ending in 0, 1, 2 or ,. If that is what you want, then it "works", but it would be better written as ls *[0-2,] or ls *[012,].
    – Kusalananda
    Mar 26, 2021 at 21:27

4 Answers 4

17

[...] matches one character (collating element in some shells) if it's in the specified set.

[10-12] means either character 1 or characters from 0 to 1 or character 2 so the same as [102] or [0-2]¹.

[10,11,12] means either 1, 0, ,, 1... So the same as [,0-2].

Here you want:

ls -d -- *1[0-2]

That is, (non-hidden) filenames that end in 1 followed by any of the 0, 1 or 2 characters.

Now beware that it also matches foo110 or foo112345612.

If you don't want that, then you'd need something like:

ls -d -- *[!0-9]1[0-2] 1[0-2]

That would however not match foo010

If out of foo10, foo00010, foo110 you want foo10 and foo00010 to match, then with ksh or bash -O extglob or zsh -o kshglob:

ls -d -- !(*[0-9])*(0)1[0-2]

Note that except with zsh, if any of those pattern's don't match, the patterns will be passed as-is to ls, so you may end up listing unwanted files if there are files named like that. With bash, you can set the failglob option to work around that.

zsh is the only shell that has a glob operator to match ranges of numbers.

ls -d -- *<10-12>

would match files ending in a number from 10 to 12. It would also match foo110 since that's foo1 followed by 10. You could do (with extendedglob):

ls -d -- (^*[0-9])<10-12>

though.

zsh is also the shell that introduced the {10..12} type of brace expansion (copied by ksh93 and bash a few years later).

However, like the {10,11,12} equivalent, that is not globbing. That's a form of expansion that is done before globbing.

ls -d -- *{10..12}

is first expanded to:

ls -d -- *10 *11 *12

If any of those 3 globs fails, then the command is aborted in zsh (and bash -O failglob).


¹ though note that in several shells and locales, including bash on a GNU system in a typical UTF-8 locale such as en_US.UTF-8, [0-1] may match on a lot more characters than just 0 and 1 including things like ٠۰߀०০੦૦୦௦౦౸೦൦෦๐໐༠༳၀႐០៰᠐᥆᧐᪀᪐᭐᮰᱀᱐⁰₀↉⓪⓿〇㍘꘠꣐꤀꧐꧰꩐꯰0𐆊𐒠𑁦𑃰𑄶𑇐𑋰𑑐𑓐𑙐𑛀𑜰𑣠𑱐𖩠𖭐𝟎𝟘𝟢𝟬𝟶𞥐🄀🄁🄋🄌

8

Try this :

ls *{10,11,12}

or

ls -l *{10,11,12}

(cannot show hidden files)

1
  • 3
    You can use shopt -s dotglob (in bash) if you want to see dotfiles as well.
    – user
    May 12, 2015 at 12:53
5

This should work:

ls -d -- *1[0-2]

Remember that [] represents a set of characters and in case of numbers it can go from [0-9]

1
  • 1
    [] doesn't represent a range by itself, just a pattern to match upon. the - makes it a range inside that pattern.
    – Chris Down
    May 12, 2015 at 11:37
0

ls *@(10|11|12) is what you're looking for.

This requires extglob to be enabled using shopt, i.e., shopt -s extglob. In addition, you can append that line to ~/.bashrc to permanently enable it.

For more information on why this works, see the official Bash manual page on pattern matching.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .