16

I'm trying to find all files for which there name starts with a capital letter. I have tried using the following command:

find . -type f -regex '.*\/[A-Z][^/]*'

It's finding paths with only lowercase letters. The following works:

find . -type f -regex '.*\/[ABCDEFGHIJKLMNOPQRSTUVWXYZ][^/]*'

As does:

find . -type f | grep '.*\/[A-Z][^/]*$'

I've tried all the different options for regextype, with the same result.

Why does find include lowercase letters in [A-Z]? I thought the regex for that was [a-zA-Z]. Is there any way to specify a range of only uppercase letters in find?

ctrl-alt-delor
  • 27,473
  • 9
  • 58
  • 102
Karl Bielefeldt
  • 553
  • 2
  • 4
  • 11
  • 5
    What about `LC_ALL=C find ...`? – mikeserv Oct 25 '14 at 15:12
  • That works. Could you explain why in an answer? – Karl Bielefeldt Oct 25 '14 at 15:14
  • 3
    I could try, but then you [might miss out on this](http://unix.stackexchange.com/a/87763/52934). – mikeserv Oct 25 '14 at 15:18
  • 1
    Why are you escaping the slash (`\/`)? Also what **find** are you using (`find --version`)? – Cristian Ciupitu Oct 25 '14 at 16:16
  • The version is GNU 4.4.2. Escaping the slash is just an old habit from perl or somewhere, I guess. – Karl Bielefeldt Oct 25 '14 at 16:21
  • The Unicode standard has something interesting about [locale-dependent ranges](http://www.unicode.org/reports/tr18/tr18-5.1.html#Locale%20Dependent%20Ranges): "Locale-dependent character ranges will include locale-dependent graphemes, as discussed above. This broadens the set of graphemes — in traditional Spanish, for example, `b-d` would match against `ch`. Languages may also vary whether they consider lowercase below uppercase or the reverse. This can have some surprising results: [a-Z] may not match anything if Z < a in that locale!". By the way, what does the `locale` command say? – Cristian Ciupitu Oct 25 '14 at 17:07
  • `locale` shows `en_US.UTF-8` for everything. – Karl Bielefeldt Oct 25 '14 at 17:26
  • 1
    Escaping `/` is only necessary when you're using it as a delimiter, e.g. in `s/foo\/bar/foobar/`. (But often you can use some other delimiter: `s#foo/bar#foobar#`.) – deltab Oct 26 '14 at 04:32

1 Answers1

42

You don't need to use -regex. You can use -name instead.

find . -type f -name "[[:upper:]]*"
Costas
  • 14,806
  • 20
  • 36