Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This question already has an answer here:

So say I'm in a directory that is deep within a file structure, such as

/home/cory/projects/foo/bar/bash/baz

I know that in either the current folder baz or one of the folders above me (such as home, cory, projects, foo, bar, or bash) there is a file named happy. How can I find that file without searching a lot of extra folders?

share|improve this question

marked as duplicate by slm Mar 30 at 12:30

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3 Answers 3

up vote 10 down vote accepted
#!/bin/bash

function upsearch () {
    test / == "$PWD" && return || test -e "$1" && echo "found: " "$PWD" && return || cd .. && upsearch "$1"
}

This function will walk up from the current dir. Note, that it is a function, and will change the directory, while traversing. It will stop in the directory, where it finds the file, and will walk up to the root / if not.

You might want to change it to a script instead of a function, and maybe jump back, if the file isn't found in the root directory.

If you never want to cd to the dir:

upsearch () {
  slashes=${PWD//[^\/]/}
  directory="$PWD"
  for (( n=${#slashes}; n>0; --n ))
  do
    test -e "$directory/$1" && echo "$directory/$1" && return 
    directory="$directory/.."
  done
}

This will lead to results like /home/cory/a/b/c/../../../happy if the file is in /home/cory/. If you need a cleaned path, you could do some

cd "$directory"
echo "$PWD"
cd - 

on success.

share|improve this answer
    
Remember to quote your expansions. If $PWD has a space in your test will be broken by wordsplitting. –  Chris Down Sep 20 '11 at 15:50
    
I added masking to the directories. Is it correct now? It will still fail with special characters like '*' in filenames, won't it? –  user unknown Sep 21 '11 at 2:41

I improved on @user-unknown's solution a bit by saving the current dir, performing an arbitrary test, then restoring the original dir before returning with response. It's more flexible because you can test for anything.

I also provide for an optional second argument that says how high to go.

https://gist.github.com/1577473

#!/bin/bash

# Use this script instead of ~/.rvm/bin/rvm-prompt
# and the output of rvm-prompt will show up in your command prompt
# only if you are in a Ruby project directory.

# see http://stackoverflow.com/a/4264351/270511
# and http://unix.stackexchange.com/questions/13464/is-there-a-way-to-find-a-file-in-an-inverse-recursive-search

upsearch () {
  the_test=$1
  up_to=$2
  curdir=`pwd`
  result=1

  while [[ "`pwd`" != "$up_to" && "`pwd`" != '/' ]]; do
    if eval "[[ $the_test ]]"; then
      result=0
      break
    fi
    cd ..
  done
  cd $curdir
  return $result
}

if upsearch '-e Gemfile || ! -z "$(shopt -s nullglob; echo *.gemspec *.rb)"' ; then
  ~/.rvm/bin/rvm-prompt
fi
share|improve this answer

Take a look at the -mindepth and -maxdepth options to find.

find won't traverse directories in a backwards direction, but you can approach it in the regular direction and limit the depth of the search.

For example:

find /home /home/cory /home/cory/projects /home/cory/projects/foo /home/cory/projects/foo/bar /home/cory/projects/foo/bar/bash -maxdepth 0 -name happy -print
share|improve this answer
    
That's not going to help. Either you use -maxdepth 0 or -maxdepth 1, in which case find isn't useful, or you don't, in which case you traverse plenty of extraneous directories for no reason. –  Gilles May 19 '11 at 23:02
    
It is a working solution. I have added an example to clarify this. –  gjb May 19 '11 at 23:21
    
You're missing the step where you generate the list of directories from $PWD or some argument. And if you're going to do that, you don't need find (ok, you can call it, but it won't be very useful). –  Gilles May 19 '11 at 23:24
    
The question was "How can I find that file without searching a lot of extra folders?". I accept that this might not be the most elegant solution, but it gets the job done without searching any extra folders. –  gjb May 19 '11 at 23:32

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