Skip to content

Find It

Introduction

Lately, my projects folder at work's gotten a bit unweildy. I still need a lot of the projects, either for maintenance or active development. Some are just for testing. But a lot of them are named things like uconn-something or something-test. It's been a little hard to rememember exactly what I've called things.

So I decided to use the terminal find command to help me out. But... after typing find . -type d -iname "*something*" -maxdepth 1 a million times I got tired of that too. So what's a developer to do when he only has 5 minutes before his next meeting, is frustrated, and wants a quick result? Write a wrapper function!

Wrapping find

The goal was to be able to type in findit plus part of a directory name, and get results. Something like findit something and get back ./uconn-something. So I started with this

findit() {
  find . -type d -iname "*$1*" -maxdepth 1
}

Let's break this down. The $1 means the first argument to come after the command. Other numbers ($2 -> $n) would mean that many more arguments. More on that in a moment. The part -iname "*$1*" does a case insensitive search for the name. The two asterisks are wildcards. This way I can find things that are close to what I remember even if I'm a little off.

But, this has some problems.

  • I can only find things in the current directory because they're locked to ..
  • I can only find directories, not files
  • I can only search 1 level deep (just the current directory again)

"Well I can fix that" I said to myself!

findit() {
  find $4 -type $3 -iname "*$1*" -maxdepth $2
}

Now I can perform a search like findit something 2 f ../. That way I can look for all files called something a level above the current directory and in the current directory.

But this also isn't so great...

If I leave off the arguments, there are no defaults. That means I have to set them every time I search. I'm hardly better off than when I started!

"I can fix that!" (I said again). Default arguments take the form ${1:-default}. The whole point of this function is to find things I can't remember the name of, so let's not set a default for that. But, I can set defaults for the rest.

findit() {
  local depth=${2:-1}
  local type=${3:-d}
  local dir=${4:-.}
  find $dir -type $type -iname "*$1*" -maxdepth $depth
}

Now I can do findit something and find directories that contain the word "something" in the name in the current directory. I can also do findit something 2 to include directories one level down. The other arguments work the same way.

Conclusion

This is definitely not perfect, for instance you can't really skip an argument. You'd need to do something like findit something 2 "" /example to use the default third argument but also find something in /example. However, my bash scripting skills aren't particularly good (or existant) and this solved the problem I had in the time I had available. Maybe I'll write a proper bash script later to manage this all a little better. In the meantime, I hope you liked this!