167

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" ?

210

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

find . -iname "WSFY321.c"
  • 6
    Also, since you're specifically looking for a file you can probably shave another couple of ticks off that with the -type f flag so it won't bother looking at the name if the inode is a directory. But that's pedantic levels of optimization... – Shadur Feb 20 '12 at 9:47
  • For working with some regex you can do find . -iname \*WSFY321.c\* -type f – Benj Jun 11 '16 at 22:01
40

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 6: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 7: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 Feb 20 '12 at 10:08
  • 5
    @Bernhard Consistency. – Gilles Feb 20 '12 at 10:08
  • 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
1

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')"
  • 1
    On macOS Sierra the -iname option is available by default. – ThomasW May 25 '17 at 1:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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