Bagaimana cara membuat `cd dir / filename` membawa saya ke dir /?


10

Saya akan merasa sangat nyaman untuk dapat menggunakan cddengan berkas argumen.

cd myDirectory/anyname.anyExtension akan setara dengan cd myDirectory/

Apa alias atau fungsi terbaik untuk mencapai perilaku ini?

EDIT : Maaf saya tidak menyebutkannya di tempat pertama: Saya menggunakanzsh

Jawaban:


5

Dalam zsh, saya sering melakukan:

cd /path/to/somefile(:h)

( huntuk head).

Jika somefilesymlink, Anda juga dapat melakukan:

cd somefile(:A:h)

Untuk sampai ke direktori tempat target symlink dapat ditemukan.


The zshsetara dengan Chris' sekarang bashsolusi -hanya akan:

cd() {
  [[ ! -e $argv[-1] ]] || [[ -d $argv[-1] ]] || argv[-1]=${argv[-1]%/*}
  builtin cd "$@"
}

Di zsh, Anda juga dapat mendefinisikan kembali "kata" yang Ctrl-Wdihapus.

Dalam zsh, "kata-kata" dalam konteks gerakan berbasis kata / transpose / hapus widget adalah urutan alnum ditambah karakter dalam $WORDCHARSvariabel yang secara default termasuk /.

Anda dapat menghapus /dari $WORDCHARSsehingga Ctrl-Whanya menghapus satu komponen jalan:

WORDCHARS=${WORDCHARS/\/}

Ekstensi lain yang bermanfaat adalah select-word-stylewidget yang dapat Anda gunakan untuk secara interaktif memilih antara berbagai gaya kata.

autoload select-word-style
zle -N select-word-style
bindkey '\ew' select-word-style

Kemudian menekan Alt-Wmemungkinkan Anda untuk memilih di antara gaya kata yang berbeda.

$ cd /blah/blih<Alt-W>
Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?

Menarik. (Saya menggunakan zsh juga).
— Sébastien

Sunting yang sangat menarik tentang kekuatan zshdan gaya kata. Terima kasih juga atas zshperintahnya. Itu melakukan pekerjaan dengan sempurna.
— Sébastien

15

Saya berasumsi Anda masih ingin mempertahankan fungsi asli jika Anda memasukkan direktori, dan Anda gunakan bash.

cd() {
    local file="${!#}"

    if (( "$#" )) && ! [[ -d "$file" ]]; then
        builtin cd "${@:1:($#-1)}" "${file%/*}"
    else
        builtin cd "$@"
    fi
}

Jika Anda tidak akan pernah menggunakan opsi cd ( -P, dll), maka ini juga sudah cukup:

cd() { 
    if [ -d "$1" ] || [ -z "$1" ]; then
        builtin cd "$@"
    else
        builtin cd "${1%/*}"
    fi
}

4
jika Anda mengubah nama fungsi menjadi cd pastikan untuk menambahkan builtindi depan cdpanggilan
— Ulrich Dangel

@ Chris: Anda berasumsi benar;) Terima kasih atas fungsi siap pakai ini
— Sébastien

Versi yang mempertahankan cdopsi tidak berfungsi zsh. Yang lebih sederhana berfungsi dengan baik zsh, TETAPI cdtidak lagi setara dengan cd ~: /
— Sébastien

@Sebastien Coba sekarang, saya pikir itu harus memperbaikinya.
— Chris Down

@ Chris, memang menambahkan tanda centang [ -z "$1" ]sudah cukup. Saya telah menerima jawaban Stephane untuk memberikan lebih banyak visibilitas, karena tampaknya itu adalah solusi terbaik untuk itu zsh.
— Sébastien

7

Anda dapat menggunakan dirnameuntuk menghapus nama file dari path, misalnya

mycd() { cd "$(dirname "$1")"; }

Lihat man dirname.


3
Perhatikan bahwa jika Anda memasukkan direktori, ini akan berubah ke direktori di atas direktori itu, yang mungkin tidak diinginkan (tidak jelas dari pertanyaan apakah ini diinginkan atau tidak).
— Chris Down

1
@ ChrisDown Benar, tapi saya meninggalkannya sebagai latihan untuk pembaca dan jawaban Anda menunjukkan bagaimana menghadapinya.
— Adrian Frühwirth

1
@ AdrianFrühwirth Latihan! Hah!

3

Jika Anda menambahkan ini ke Anda .profile, lalu muat ( source ~/.profileatau logout dan masuk lagi), maka mycd [file or directory]akan membawa Anda ke direktori yang benar:

mycd() { if [ -d "$1" ]; then cd "$1"; else cd "$( dirname "$1" )"; fi ; }

Jika Anda menyebutkannya cd, maka hal-hal aneh akan terjadi.


1
Ini akan pecah jika nama direktori berisi spasi putih, dan Anda memerlukan tanda koma penutup untuk mengakhiri grup perintah. Diedit untuk Anda, harap Anda tidak keberatan.
— Chris Down

@ ChrisDown, meskipun itu berlaku untuk kerang lain, Anda tidak perlu titik koma penutup zsh.
— Stéphane Chazelas

Juga, ini pecah jika melewati argumen untuk cd, suka -P.
— Chris Down

0
cd2() {
 arg=() dir= cmd= IFS=" " msg='[-L|[-P [-e]]|-h] [dir|file]'

 while [ "$#" -gt 1 ] ; do
  case "$1" in
   -h) printf "%s: cd2 %s\n" "$0" "$msg"
    return 1 ;;
   *) arg+=("$1") ;;
  esac
  shift
 done

 [ -f "${1:-}" ] && dir="$(dirname ${1:-})" || dir="${1:A}"
 [ ! -z "$arg" ] && cmd="cd ${arg[@]} $dir" || cmd="cd $dir"

 if ! $cmd 2>/dev/null; then
  printf "%s: cd2 %s\n" "$0" "$msg"
  return 1
 fi
}

Diberi nama direktori $(sudo reboot), fungsi ini dapat mem-boot ulang sistem. Juga, pengguna menggunakan zsh, bukan bash.
— Kusalananda

Berikan perintah $ (sudo reboot), fungsi ini akan reboot sistem. Juga, +1 pada awalnya saya tidak melihat 'zsh' - tangkapan yang bagus.
— ecwpz91

Tidak, cd '$(sudo reboot)'akan mengubah direktori, sementara fungsi Anda akan mencoba untuk mengevaluasi nama.
— Kusalananda

Ah, saya melihat dan membuat perubahan. Beri tahu saya jika itu berhasil? Tangkapan yang bagus.
— ecwpz91
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.