Versi yang lebih umum yang memungkinkan menggunakan find
opsi:
#!/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
Misalnya (dengan asumsi skrip disimpan sebagai find_up.sh
)
find_up.sh some_dir -iname "foo*bar" -execdir pwd \;
... akan mencetak nama-nama semua some_dir
leluhur (termasuk dirinya sendiri) hingga /
di mana file dengan pola ditemukan.
Saat menggunakan readlink -f
skrip di atas akan mengikuti symlinks di jalan, seperti yang tercantum dalam komentar. Anda dapat menggunakan realpath -s
sebagai gantinya, jika Anda ingin mengikuti jalur berdasarkan nama ("/ foo / bar" akan naik ke "foo" bahkan jika "bar" adalah symlink) - namun itu membutuhkan pemasangan realpath
yang tidak diinstal secara default pada kebanyakan platform.
realpath -s
untuk mendapatkan perilaku yang Anda inginkan.readlink
bukan bagian dari standar. Script portabel dapat diimplementasikan dengan hanya fitur shell POSIX.find
ataureadlink
. Saya sarankan mengubahnya menjadi sesuatu seperti$curpath
itu supaya tidak membayangi variabel shell.akan mencetak direktori tingkat atas dari repositori saat ini, jika Anda berada dalam satu.
Opsi terkait lainnya:
sumber
Versi umum jawaban Gilles, parameter pertama yang digunakan untuk menemukan kecocokan:
Tetap menggunakan sym-link.
sumber
Temukan tidak dapat melakukannya. Saya tidak bisa memikirkan sesuatu yang lebih sederhana dari pada shell loop. (Belum diuji, menganggap tidak ada
/.git
)Untuk kasus tertentu dari repositori git, Anda dapat membiarkan git melakukan pekerjaan untuk Anda.
sumber
Jika Anda menggunakan zsh dengan globbing diperpanjang diaktifkan, Anda bisa melakukannya dengan oneliner:
Penjelasan (dikutip dari
man zshexpn
):Kredit:
Faux
aktif#zsh
untuk saran awal penggunaan(../)#.git(:h)
.sumber
(../)
yang dilakukan ... Oh, dan siapa / apaFaux on #zsh
?(../)
sendiri tidak berarti banyak, tetapi(../)#
berarti mencoba untuk memperluas pola di dalam tanda kurung 0 atau lebih kali, dan hanya menggunakan yang benar-benar ada pada sistem file. Karena kami memperluas dari 0 ke direktori induk, kami secara efektif mencari ke atas ke akar sistem file (catatan: Anda mungkin ingin menambahkan sesuatu setelah pola untuk membuatnya bermakna, tetapi untuk pelaksanaan pencerahanprint -l (../)#
). Dan#zsh
merupakan saluran IRC,Faux
adalah nama pengguna di dalamnya.Faux
menyarankan solusi, oleh karena itu kredit.(../)#.git(/Y1:a:h)
berhenti di yang pertama ditemukan (dengan versi terbaru dari zsh)setopt extended_glob
Versi findup ini mendukung sintaks "find", seperti jawaban @ sinelaw, tetapi juga mendukung symlink tanpa memerlukan realpath. Ini juga mendukung fitur "berhenti di" opsional, jadi ini berfungsi:
findup .:~ -name foo
... mencari foo tanpa melewati direktori home.sumber
Saya telah menemukan bahwa bekerja dengan symlink membunuh beberapa opsi lain. Terutama jawaban spesifik git. Saya sudah setengah jalan membuat favorit saya sendiri dari jawaban asli ini yang cukup efisien.
Saya menggunakan symlinks untuk proyek go saya karena go ingin kode sumber di lokasi tertentu dan saya suka menyimpan proyek saya di bawah ~ / proyek. Saya membuat proyek dalam $ GOPATH / src dan menghubungkannya dengan ~ / proyek. Jadi menjalankan
git rev-parse --show-toplevel
mencetak direktori $ GOPATH, bukan direktori ~ / projects. Solusi ini memecahkan masalah itu.Saya menyadari ini adalah situasi yang sangat spesifik, tetapi saya pikir solusinya sangat berharga.
sumber
Solusi Vincent Scheib tidak berfungsi untuk file yang berada di direktori root.
Versi berikut tidak, dan juga memungkinkan Anda melewati dir mulai sebagai argumen 1.
sumber
Saya memodifikasi solusi sinelaw menjadi POSIX. Itu tidak mengikuti symlink dan termasuk mencari direktori root dengan menggunakan do while.
sumber