281

I am looking for file "WSFY321.c" in a huge directory hierarchy.
Usually I would use GNU find: find . -name "WSFY321.c"
But I do not know the case, it could be uppercase, lowercase, or a mix of both.

What is the easiest way to find this file?
Is there something better than find . | grep -i "WSFY321.c" ?

3 Answers3

375

Recent versions of GNU find have an -iname flag, for case-insensitive name searches.

find . -iname "WSFY321.c"
d-cubed
  • 204
55

With GNU find, or other versions of find that have it:

find . -iname 'WSFY321.c'

With other versions:

find . -name '[Ww][Ss][Ff][Yy]321.[Cc]'

Or a compromise that's slower but easier to type:

find . -name '????321.c' | grep -i '/WSFY[^/]*$'

Or in zsh:

print -rl -- **/(#i)WSFY321.c
  • @Gilles The grep version is filtering only upper case, and I don't understand the '[^/]' ..(not /) – Peter.O Feb 20 '12 at 06:22
  • @Gilles What is the argument to use the single quotes in the first case (exact filename) over no quotes at all? – Bernhard Feb 20 '12 at 07:14
  • @Peter.O No * after the / in the bash version. I meant grep -i. I use [^/]* rather than .* so as not to catch files in directories whose name begins with WSFY. – Gilles 'SO- stop being evil' Feb 20 '12 at 10:08
  • 6
  • Thanks Gilles: I deleted the previous comment with incorrect syntax, and tested the ammended version, but it doesn't work without the * (for an unexpected reason; to me at least).  The case-insensitive option no longer works: shopt -s extglob nocaseglob globstar; printf '%s\n' **/WSFY321.c ... I suppose that's why it is called a nocase‍​ *glob*: it only works in the context of a glob (or so it seems). – Peter.O Feb 20 '12 at 11:34
  • PS: Here is a way to use bash's nocaseglob without using the asterisk ***** wildcard: shopt -s extglob nocaseglob globstar; printf '%s\n' **/[W]SFY321.c ... The [] is globby enough... – Peter.O Feb 20 '12 at 11:45
  • @Peter.O Oh, I didn't expect this either. Bash is being weird. **/WSFY321.[c] does work. Zsh behaves in the same way if you use setopt no_case_glob, but using the case insensitive glob flag tells the shell that this is a glob anyway (and it's the same in ksh93 with **/~(i:WSFY321.c)). – Gilles 'SO- stop being evil' Feb 20 '12 at 11:54
  • PPS: The newer extended globing syntax in bash works without any quirky juggling involved: shopt -s extglob nocaseglob globstar; printf '%s\n' **/@(WSFY321.c) – Peter.O Feb 20 '12 at 12:10
3

Two solutions for macOS:

Using GNU find:

brew install findutils --with-default-names
# restart Terminal
find . -iname 'WSFY321.c'

Using GNU sed:

brew install gnu-sed --default-names
# restart Terminal
find -name "$(sed 's|\([[:alpha:]]\)|[\U\1\L\1]|g' <<<'WSFY321.c')"
srage
  • 131