有没有办法通过反向递归搜索来查找文件?

有没有办法通过反向递归搜索来查找文件?

假设我位于文件结构深处的目录中,例如

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

我知道在当前文件夹baz或其中一个文件夹中多于我(例如homecoryprojectsfoobarbash)有一个名为happy.如何在不搜索大量额外文件夹的情况下找到该文件?

答案1

#!/bin/bash

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

该函数将从当前目录开始。请注意,它是一个函数,并且会在遍历时更改目录。它将停在找到文件的目录中,如果没有,将走到根目录 / 。

您可能希望将其更改为脚本而不是函数,并且如果在根目录中找不到该文件,则可能会跳回来。

如果您不想 cd 到该目录:

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

如果文件位于 /home/cory/ 中,这将导致类似 /home/cory/a/b/c/../../../happy 的结果。如果你需要一条干净的道路,你可以做一些

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

关于成功。

要将搜索限制为常规文件并排除目录、符号链接等,您可以将测试更改为 -f 而不是 -e。

答案2

查看-mindepth-maxdepth的选项find

find不会向后遍历目录,但您可以按常规方向接近它并限制搜索深度。

例如:

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

答案3

我通过保存当前目录,执行任意测试,然后在返回响应之前恢复原始目录,对@user-unknown的解决方案进行了一些改进。它更灵活,因为您可以测试任何内容。

我还提供了一个可选的第二个参数,说明要走多高。

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

相关内容