Bash CD hingga di folder tertentu

16

Saya melakukan banyak pekerjaan di Magento, dan begitu juga banyak orang yang bekerja dengan saya, dan itu menjengkelkan harus mengetik:

cd ../../../../../../

Untuk hanya menemukan Anda masih beberapa direktori dari folder 'httpdocs' root Anda, jadi saya mencoba membuat skrip yang mengikuti pseudo-code ini:

while lowest level directory != httpdocs
    cd ../
end while;

Kelihatannya cukup sederhana, saya berasumsi saya harus melakukan beberapa bentuk grep saat memeriksa apakah bagian terakhir dari direktori kerja saat ini adalah httpdocs, jika tidak terus naik level sampai itu benar.

Saya sudah mencari belajar bash untuk ini, meskipun sepertinya harus ada sesuatu di luar sana yang mirip, dan sintaksnya membuat saya bingung sampai akhir.

pengguna652650
sumber

Jawaban:

8

Ini harus menjadi fungsi shell , bukan skrip, karena skrip dieksekusi di shell baru (dan dengan demikian tidak dapat mengubah direktori shell asli).

function cdroot()
{
  while [[ $PWD != '/' && ${PWD##*/} != 'httpdocs' ]]; do cd ..; done
}

Tentu saja Anda dapat memberi nama fungsi apa pun yang Anda suka.

Beberapa penjelasan: Tes pertama ( $PWD != '/') adalah gagal jika Anda melakukannya cdrootketika Anda tidak berada di dalam folder httpdocs. Ini akan berhenti ketika Anda sampai ke root.

Tes kedua ( ${PWD##*/} != 'httpdocs') sedikit lebih rumit. $PWDadalah variabel yang berisi lintasan direktori saat ini. ${PWD##*/}memotong semuanya hingga dan termasuk tebasan terakhir.

cjm
sumber
Kelemahan dari yang berulang ini adalah bahwa Anda kehilangan kemampuan untuk hanya melakukan cd -setelahnya untuk kembali ke tempat Anda berada.
Ezequiel Muns
27

Saya memiliki fungsi yang disebut uptodi .bashrc saya yang memungkinkan Anda untuk naik ke direktori apa pun di jalur saat ini dengan nama:

upto ()
{
    if [ -z "$1" ]; then
        return
    fi
    local upto=$1
    cd "${PWD/\/$upto\/*//$upto}"
}

Saya juga memiliki penyelesaian untuk fungsi ini, sehingga memberi saya nama direktori yang valid dan penyelesaian ketika saya menekan tab:

_upto()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    local d=${PWD//\//\ }
    COMPREPLY=( $( compgen -W "$d" -- "$cur" ) )
}
complete -F _upto upto

Selain itu, saya memiliki fungsi lain jdyang memungkinkan saya untuk beralih ke direktori apa pun di bawah yang sekarang:

jd(){
    if [ -z "$1" ]; then
        echo "Usage: jd [directory]";
        return 1
    else
        cd **"/$1"
    fi
}

Contoh:

[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto h[TAB][TAB]
habitat       hippopotamus
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto hippopotamus
[/www/public_html/animals/hippopotamus] $ jd images
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ 
dogbane
sumber
Anda juga bisa menambahkan alias untuk upto httpdocs.
cjm
@drogbane: jdtampaknya tidak berfungsi di setiap kasus, maukah Anda menjelaskan cara kerjanya?
Cesar
@Cesar ini menggunakan globstar ( **). Untuk mengaktifkan fitur ini dalam penggunaan bash shell Anda shopt -s globstar.
dogbane
2
Ini dilakukan dengan sangat cemerlang, saya berharap saya bisa dua kali memilih.
droope
1
Saya telah memasukkan deteksi shopt dinamis dan aktivasi dalam jdfungsi, lihat gist.github.com/Rob--W/5888648 . Saya hanya mengujinya dengan Bash 4.2.45, jadi YMMV.
Rob W
5

Fungsi bash paling sederhana yang dapat Anda masukkan ke dalam Anda .bashrcyang dapat saya pikirkan (sederhana karena tidak menggunakan loop atau proses eksternal) adalah:

cdup() {
    cd "${PWD/\/httpdocs\/*//httpdocs}"
}

Ini menggunakan Pola substitusi ekspansi parameter untuk menggantikan semuanya setelah /httpdocs/di $PWDdengan `/ httpdocs'. Ini terlihat sangat berantakan karena kita harus melarikan diri dari garis miring ke depan untuk membedakannya dari garis miring ke depan dalam sintaks ekspansi bash. Plus jangan luput ke depan garis miring pada string pengganti, sehingga juga terlihat tidak konsisten.

Jika tidak ada /httpdocs/di jalur saat ini maka tidak ada pergantian akan dilakukan dan itu hanya akan berubah ke direktori saat ini.

Misalnya, substitusi akan diganti /a/b/c/httpdocs/e/f/gdengan /a/b/c/httpdocsdan cdke dalam direktori itu.

Fungsi tersebut harus berada di lingkungan shell Anda saat ini (baik sebagai fungsi atau alias) karena proses anak tidak dapat mengubah direktori saat ini dari induknya. Inilah mengapa saya mengatakan untuk meletakkannya di .bashrcskrip shell Anda dan bukan di skrip shell.

camh
sumber
Secara kebetulan, perlu disebutkan bahwa ini akan membawa Anda setinggi mungkin dalam hierarki (yang mungkin merupakan use case yang paling berguna).
Ibrahim
3

Anda juga dapat memasukkan sesuatu seperti ini di profil Anda:

alias cdh='cd $(echo $PWD | sed -e "s/\(.*\/httpdocs\)\/.*/\1/")'

Pengetikan yang adil cdhakan membawa Anda ke httpdocsdirektori paling atas di jalur Anda saat ini.

Tikar
sumber
2

Itu tidak sepenuhnya mengatasi masalah Anda, tetapi itu akan menghemat melakukan cd ../../../../../../sedikit. Saya sudah meminjam ini dari pengguna yang tidak dikenal pos di sini .


up N

lompat N direktori di pohon direktori

Alih-alih mengetik

cd ../../../..

Anda cukup mengetik

up 4

dan a

cd -    

akan membawamu kembali

Masukkan fungsi ke dalam .bashrc Anda untuk menggunakannya.

# (c) 2007 stefan w. GPLv3          
function up {
ups=""
for i in $(seq 1 $1)
do
        ups=$ups"../"
done
cd $ups
}
boehj
sumber