find 在父目录而不是子目录中搜索

find 在父目录而不是子目录中搜索

我嵌套在文件树深处,我想找到哪个父目录包含文件。

例如,我位于一组嵌套的 GIT 存储库中,想要找到.git控制我当前所在文件的目录。我希望有类似的东西

find -searchup -iname ".git"

答案1

git rev-parse --show-toplevel

如果您位于当前存储库中,将打印出当前存储库的顶级目录。

其他相关选项:

# `pwd` is inside a git-controlled repository
git rev-parse --is-inside-work-tree
# `pwd` is inside the .git directory
git rev-parse --is-inside-git-dir

# path to the .git directory (may be relative or absolute)
git rev-parse --git-dir

# inverses of each other:
# `pwd` relative to root of repository
git rev-parse --show-prefix
# root of repository relative to `pwd`
git rev-parse --show-cdup

答案2

吉尔斯答案的通用版本,第一个参数用于查找匹配:

find-up () {
  path=$(pwd)
  while [[ "$path" != "" && ! -e "$path/$1" ]]; do
    path=${path%/*}
  done
  echo "$path"
}

保留符号链接的使用。

答案3

一个更通用的版本,允许使用find选项:

#!/bin/bash
set -e
path="$1"
shift 1
while [[ $path != / ]];
do
    find "$path" -maxdepth 1 -mindepth 1 "$@"
    # Note: if you want to ignore symlinks, use "$(realpath -s "$path"/..)"
    path="$(readlink -f "$path"/..)"
done

例如(假设脚本另存为find_up.sh

find_up.sh some_dir -iname "foo*bar" -execdir pwd \;

...将打印 的所有祖先(包括其自身)的名称,some_dir直到/找到具有该模式的文件为止。

当使用readlink -f上面的脚本时,将遵循符号链接,如注释中所述。realpath -s如果您想按名称跟踪路径(即使“bar”是符号链接,“/foo/bar”也会上升到“foo”),您可以使用相反的方法 - 但这需要安装realpath默认情况下未安装的大多数平台。

答案4

发现做不到。我想不出还有什么比 shell 循环更简单的了。 (未经测试,假设没有/.git

git_root=$(pwd -P 2>/dev/null || command pwd)
while [ ! -e "$git_root/.git" ]; do
  git_root=${git_root%/*}
  if [ "$git_root" = "" ]; then break; fi
done

对于 git 存储库的特定情况,您可以让 git 为您完成工作。

git_root=$(GIT_EDITOR=echo git config -e)
git_root=${git_root%/*}

相关内容