我嵌套在文件树深处,我想找到哪个父目录包含文件。
例如,我位于一组嵌套的 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%/*}