240

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 Answers 3

318

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

find . -iname "WSFY321.c"
3
  • 7
    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, 2012 at 9:47
  • For working with some regex you can do find . -iname \*WSFY321.c\* -type f
    – Benj
    Jun 11, 2016 at 22:01
  • This pattern of adding -i before an option follows for other find options too. Ex: -name to search for a name, and -iname to make it case-insensitive. -path to search for a path, and -ipath to make it case-insensitive. I mention using -ipath in my answer here: Stack Overflow: How to exclude a directory in find . command. Nov 3, 2021 at 19:40
50

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
8
  • @Gilles The grep version is filtering only upper case, and I don't understand the '[^/]' ..(not /)
    – Peter.O
    Feb 20, 2012 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, 2012 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. Feb 20, 2012 at 10:08
  • 6
    @Bernhard Consistency. Feb 20, 2012 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, 2012 at 11:34
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')"
1
  • 2
    On macOS Sierra the -iname option is available by default.
    – ThomasW
    May 25, 2017 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.