chaos
chaos

Reputation: 124307

What is up with [A-Z] meaning [A-Za-z]?

I've noticed for a while now that, on some of the Unix-based systems I use at least, ls [A-Z]* has been giving me the results I would anticipate from ls [A-Za-z]*, leaving me unable to easily get a list of just the goddamned files that start with capital letters. I just now ran into the same thing with grep, where I could not get it to stop matching lowercase letters with [A-Z] until I eventually used grep -P to get Perl regex.

So I have some related questions:

  1. When did this idiocy start?
  2. Who is responsible and needs to be punished?
  3. WHY???
  4. Is there some reasonably simple workaround for either or both of the ls and grep cases? (Trying, for example, grep --no-ignore-case was fruitless. grep -P is not a very good workaround because of its experimental feature status.)

Upvotes: 12

Views: 4963

Answers (3)

Ether
Ether

Reputation: 53976

Unix shells don't actually use regular expressions, but glob patterns, which are distinctly different from regexes. One difference is that they are implicitly anchored to the start and end of the string - e.g. ls foo[a-z] will list the file food, but not fooble. It's not actually ls doing the matching here, but the shell itself. Globs are also usually sometimes case insensitive (depending on the implementation).

Take a look at the manpage for your favourite interactive shell and read about glob matching - for example bash's manpage about filename expansion describes the syntax it uses.

Upvotes: -1

peoro
peoro

Reputation: 26060

It depends on your locale. If you want that [A..Z] only matches capital letters, you could use C locale: set LC_COLLATE or LC_ALL to C.

LC_ALL=C
ls [A..Z]*

bash manual, pattern matching

Upvotes: 3

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798744

It's actually [A-Za-y], and it has to do with language collation. If you want to override it then set $LC_COLLATE appropriately; either of C or POSIX should do.

Upvotes: 15

Related Questions