Bash – find closest matching folder

bashcd-commanddirectoryshellshell-script

What is the best way to sort the results of $ find . -name scripts -type d by the occurrences of '/' and then choose the first result?

I want to create a function that would cd down to a common folder in a project. I wanted it to be flexible based on your relative directory.

So if I have 10 projects all with similar folder structure:

~/project-a/project/folder/structure
~/project-b/project/folder/structure
~/project-c/project/folder/structure

I could:

$ cd ~/project-a
$ cdd structure

And be dropped down into ~/project-a/project/folder/structure

Update

I'm unable to sort results in any predictable way, example:

$ find . -type d -name "themes"

./wp-content/plugins/contact-form-7/includes/js/jquery-ui/themes
./wp-content/plugins/jetpack/modules/infinite-scroll/themes
./wp-content/plugins/smart-youtube/themes
./wp-content/plugins/wptouch-pro/themes
./wp-content/themes
./wp-includes/js/tinymce/themes

I'd like the cdd function to drop down to the closest result. In this example it'd be ./wp-content/themes.

Best Answer

With zsh, you could do:

cdd() cd -- **/$1(/Od[1])

cdd themes

That cdd function finds all the files of type directory (/) with the name given as argument ($1), Orders them by depth and selects the first one ([1]).

Where it's not very efficient is that it crawls the whole directory tree (skipping hidden directories, add the D glob qualifier to change that) even when there's a matching directory in the current directory.

To traverse the directory tree one level of depth at a time, you could do instead:

cdd() {
  local dirs matches
  dirs=(.)
  while (($#dirs)) {
    matches=($^dirs/$1(N/[1]))
    if (($#matches)) {
      cd $matches[1]
      return
    }
    dirs=($^dirs/*(/N))
  }
  print >&2 Not found
  return 1
}
Related Question