Làm thế nào để tạo `cd dir / filename` đưa tôi đến dir /?


10

Tôi sẽ thấy nó rất thuận tiện để có thể sử dụng cdvới một đối số tệp .

cd myDirectory/anyname.anyExtension sẽ tương đương với cd myDirectory/

Điều gì sẽ là bí danh hoặc chức năng tốt nhất để đạt được hành vi này?

EDIT : Xin lỗi tôi đã không đề cập đến nó ở vị trí số 1: Tôi sử dụngzsh

Câu trả lời:


5

Trong zsh, tôi thường làm:

cd /path/to/somefile(:h)

( hcho head).

Nếu somefilelà một liên kết tượng trưng, ​​bạn cũng có thể làm:

cd somefile(:A:h)

Để đến thư mục nơi có thể tìm thấy mục tiêu của symlink.


Các zshtương đương với Chris' bây giờ bashgiải pháp -only sẽ là:

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

Trong zsh, bạn cũng có thể xác định lại những gì "từ" Ctrl-Wloại bỏ.

Trong zsh, "từ" trong ngữ cảnh của các tiện ích chuyển động / chuyển đổi / xóa dựa trên từ là các chuỗi của alnums cộng với các ký tự trong $WORDCHARSbiến mà theo mặc định bao gồm /.

Bạn có thể xóa /từ $WORDCHARSđó để Ctrl-Wchỉ xóa một thành phần đường dẫn:

WORDCHARS=${WORDCHARS/\/}

Một tiện ích mở rộng hữu ích khác là select-word-styletiện ích mà bạn có thể sử dụng để lựa chọn tương tác giữa các kiểu từ khác nhau.

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

Sau đó nhấn Alt-Wcho phép bạn chọn giữa các kiểu từ khác nhau.

$ 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
?

Hấp dẫn. (Tôi cũng dùng zsh).
Sébastien

Chỉnh sửa rất thú vị về sức mạnh của zshphong cách và từ. Cảm ơn bạn cũng cho zshlệnh. Nó làm công việc hoàn hảo.
Sébastien

15

Tôi giả sử bạn vẫn muốn giữ lại chức năng ban đầu nếu bạn nhập một thư mục và bạn đang sử dụng bash.

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

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

Nếu bạn sẽ không bao giờ sử dụng các tùy chọn của cd ( -P, v.v.), thì điều này cũng sẽ đủ:

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

4
nếu bạn thay đổi tên hàm thành cd, hãy đảm bảo thêm builtinvào trước các cdcuộc gọi
Ulrich Dangel

@Chris: Bạn đã giả sử đúng;) Cảm ơn vì chức năng này đã sẵn sàng để sử dụng
Sébastien

Phiên bản bảo tồn cdcác tùy chọn không hoạt động zsh. Đơn giản hơn hoạt động tốt với zsh, NHƯNG cdkhông còn tương đương như cd ~: /
Sébastien

@Sebastien Hãy thử ngay bây giờ, tôi nghĩ rằng nên khắc phục điều đó.
Chris Xuống

@Chris, thực sự thêm một kiểm tra [ -z "$1" ]là đủ. Tôi đã chấp nhận câu trả lời của Stephane để cho nó rõ hơn, vì nó dường như là giải pháp tốt nhất cho zsh.
Sébastien

7

Bạn có thể sử dụng dirnameđể tách tên tệp khỏi đường dẫn, vd

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

Xem man dirname.


3
Lưu ý rằng nếu bạn nhập một thư mục, điều này sẽ thay đổi thành thư mục phía trên thư mục đó, điều này có thể không mong muốn (không rõ ràng từ câu hỏi liệu điều này có được mong muốn hay không).
Chris Xuống

1
@ChrisDown Đúng, nhưng tôi đã để nó như một bài tập cho người đọc và câu trả lời của bạn cho thấy cách đối phó với nó.
Adrian Frühwirth

1
@ AdrianFrühwirth Một bài tập! Hừ!

3

Nếu bạn thêm cái này vào .profile, sau đó tải nó ( source ~/.profilehoặc đăng xuất và đăng nhập lại), sau đó mycd [file or directory]sẽ đưa bạn đến đúng thư mục:

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

Nếu bạn đặt tên cho nó cd, thì những điều kỳ lạ sẽ xảy ra.


1
Điều này sẽ phá vỡ nếu tên thư mục chứa khoảng trắng và bạn cần một dấu chấm phẩy đóng để chấm dứt nhóm lệnh. Chỉnh sửa nó cho bạn, hy vọng bạn không phiền.
Chris Xuống

@ChrisDown, mặc dù điều đó đúng với các shell khác, bạn không cần dấu chấm phẩy đóng zsh.
Stéphane Chazelas

Ngoài ra, điều này phá vỡ nếu vượt qua args để cd, như -P.
Chris Xuống

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
}

Đưa ra một thư mục được gọi $(sudo reboot), chức năng này có thể khởi động lại hệ thống. Ngoài ra, người dùng đang sử dụng zsh, không bash.
Kusalananda

Đưa ra bất kỳ lệnh $ (sudo restart), chức năng này sẽ khởi động lại hệ thống. Ngoài ra, +1 tôi không nhận thấy 'zsh' ban đầu - bắt tốt.
ecwpz91

Không, cd '$(sudo reboot)'sẽ thay đổi thư mục, trong khi chức năng của bạn sẽ cố gắng đánh giá tên.
Kusalananda

Ah, tôi thấy và thực hiện thay đổi. Cho tôi biết nếu nó hiệu quả? Nắm bắt tốt.
ecwpz91
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.