Еще более общая версия, которая позволяет использовать 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
вместо этого, если вы хотите следовать по пути вверх по имени («/ foo / bar» будет переходить к «foo», даже если «bar» является символической ссылкой) - однако это требует установки, realpath
которая по умолчанию не установлена в большинство платформ.
realpath -s
чтобы получить поведение, которое вы хотите.readlink
не является частью стандарта. Переносимый скрипт может быть реализован только с функциями оболочки POSIX.find
илиreadlink
.$curpath
Вместо этого я предлагаю изменить его на что-то подобное, чтобы оно не скрывало переменную оболочки.распечатает каталог верхнего уровня текущего репозитория, если вы в нем.
Другие связанные варианты:
источник
Обобщенная версия ответа Жиля, первый параметр, используемый для поиска соответствия:
Сохраняет использование сим-ссылок.
источник
Найти не могу этого сделать. Я не могу придумать ничего более простого, чем цикл оболочки. (Не проверено, предполагается, что нет
/.git
)Для конкретного случая git-репозитория вы можете позволить git сделать всю работу за вас.
источник
Если вы используете zsh с включенной расширенной глобализацией, вы можете сделать это с помощью oneliner:
Объяснение (цитата из
man zshexpn
):Кредиты:
Faux
на#zsh
для первоначального предложения использования(../)#.git(:h)
.источник
(../)
делает ... О, и кто / чтоFaux on #zsh
?(../)
себе не значит много, но(../)#
означает попытаться развернуть шаблон внутри круглых скобок 0 или более раз и использовать только те, которые действительно существуют в файловой системе. Поскольку мы расширяем от 0 до n родительских каталогов, мы эффективно ищем вверх в корне файловой системы (примечание: вы, вероятно, хотите добавить что-то после шаблона, чтобы сделать его осмысленным, но для выполнения просветленияprint -l (../)#
). И#zsh
это IRC канал,Faux
это имя пользователя на нем.Faux
предложил решение, поэтому кредит.(../)#.git(/Y1:a:h)
остановиться на первом найденном (с последней версией zsh)setopt extended_glob
Эта версия findup поддерживает синтаксис "find", как и ответ @ sinelaw, но также поддерживает символические ссылки без необходимости использования realpath. Он также поддерживает опциональную функцию "stop at", поэтому она работает:
findup .:~ -name foo
... ищет foo, не передавая домашний каталог.источник
Я обнаружил, что работа с символическими ссылками убивает некоторые другие параметры. Особенно Git конкретные ответы. Я наполовину создал своего любимого из этого оригинального ответа, который довольно эффективен.
Я использую символические ссылки для своих проектов go, потому что go хочет, чтобы исходный код находился в определенном месте, и мне нравится хранить свои проекты в ~ / projects. Я создаю проект в $ GOPATH / src и символическую ссылку на ~ / projects. Таким образом, запуск
git rev-parse --show-toplevel
распечатывает каталог $ GOPATH, а не каталог ~ / projects. Это решение решает эту проблему.Я понимаю, что это очень специфическая ситуация, но я думаю, что решение является ценным.
источник
Решение Винсента Шейба не работает для файлов, которые находятся в корневом каталоге.
Следующая версия делает, а также позволяет передать начальный каталог в качестве 1-го аргумента.
источник
Я изменил решение Sinelaw, чтобы оно было POSIX. Он не следует по символическим ссылкам и включает в себя поиск в корневом каталоге с помощью цикла do while.
источник