Làm thế nào để làm cho đối số cd trường hợp INensensitive?


9

Đôi khi, trong khi truy cập vào các thư mục khác nhau, điều đó xảy ra hầu hết các lần tôi nhớ tên hoặc ít nhất là một phần tên của thư mục trong hệ thống Linux của chúng tôi. Nhưng một số thư mục được đặt tên bắt đầu bằng chữ hoa đầu tiên hoặc một trong các ký tự ở giữa tên Chữ hoa.

Bất cứ ai cũng có thể đề nghị làm thế nào tôi có thể tạo các đối số theo cdtrường hợp lệnh INSENSITIVE, như vậy nếu tôi thực hiện cd BackupDirectoryhoặc cd backupdirectorynó có thể nhập tên thư mục BackupDirectory.

Tất nhiên, tôi không muốn làm hỏng mọi thứ cho những người dùng khác vì vậy nếu có thể, những thay đổi trên có thể được áp dụng cho phiên tôi đang sử dụng và không ảnh hưởng đến những người dùng khác?

Ok, tôi đã thử set completion-ignore-casenhưng điều này không hiệu quả. Nó chỉ giúp trong đó nếu tôi gõ cd bTabhoặc Esc Escđiền vào tên thư mục bỏ qua trường hợp. Nhưng, những gì tôi cần là nếu tôi làm một cd backupdirectory, nó chỉ bỏ qua trường hợp và BackupDirectorytự mình đi vào.


Làm thế nào bạn sẽ tránh được sự mơ hồ? Nếu bạn có backUPbackUp, làm thế nào để backupkhông có thư mục nào bạn muốn đi?
Bernhard

Bạn đang sử dụng vỏ nào?
Gert van den Berg

Bạn đã cân nhắc sử dụng một công cụ như mchoặc chuyển sang GUI chưa? Làm cho cuộc sống dễ dàng hơn nhiều.
ott--

Câu trả lời:


17

Kích hoạt cdspellsẽ giúp:

shopt -s cdspell

Từ mantrang:

cdspell Nếu được đặt, các lỗi nhỏ trong chính tả của thành phần thư mục trong lệnh cd sẽ được sửa. Các lỗi được kiểm tra là các ký tự được chuyển đổi, một ký tự sai và một ký tự quá nhiều. Nếu tìm thấy một hiệu chỉnh, tên tệp đã sửa được in và lệnh sẽ tiếp tục. Tùy chọn này chỉ được sử dụng bởi các vỏ tương tác.


Bạn có phải làm bất cứ điều gì sau khi chạy lệnh này để thay đổi có hiệu lực không?
Nathan Arthur

Tôi sẽ cho là như vậy bởi vì đơn giản là vào cdtell của shopt không làm gì cho tôi
sdfsdf

10

Bash

set completion-ignore-case ontrong ~/.inputrc(hoặc bind 'set completion-ignore-case on'trong ~/.bashrc) sẽ là đề nghị của tôi. Nếu bạn định nhập tên đầy đủ, tại sao lại chần chừ vài lần nhấn Shiftphím?

Nhưng nếu bạn thực sự muốn nó, đây là một trình bao bọc cdcố gắng cho một kết hợp chính xác và nếu không có, hãy tìm một kết quả không phân biệt chữ hoa chữ thường và thực hiện nó nếu nó là duy nhất. Nó sử dụng nocaseglobtùy chọn shell cho toàn cầu không phân biệt chữ hoa chữ thường và biến đối số thành một phần tử bằng cách nối thêm @()(không khớp với gì và yêu cầu extglob). Các extglobtùy chọn này phải được bật khi xác định chức năng, nếu không bash thậm chí không thể phân tích nó. Chức năng này không hỗ trợ CDPATH.

shopt -s extglob
cd () {
  builtin cd "$@" 2>/dev/null && return
  local options_to_unset=; local -a matches
  [[ :$BASHOPTS: = *:extglob:* ]] || options_to_unset="$options_to_unset extglob"
  [[ :$BASHOPTS: = *:nocaseglob:* ]] || options_to_unset="$options_to_unset nocaseglob"
  [[ :$BASHOPTS: = *:nullglob:* ]] || options_to_unset="$options_to_unset nullglob"
  shopt -s extglob nocaseglob nullglob
  matches=("${!#}"@()/)
  shopt -u $options_to_unset
  case ${#matches[@]} in
    0) # There is no match, even case-insensitively. Let cd display the error message.
      builtin cd "$@";;
    1)
      matches=("$@" "${matches[0]}")
      unset "matches[$(($#-1))]"
      builtin cd "${matches[@]}";;
    *)
      echo "Ambiguous case-insensitive directory match:" >&2
      printf "%s\n" "${matches[@]}" >&2
      return 3;;
  esac
}

Ksh

Trong khi tôi đang ở đây, đây là một chức năng tương tự cho ksh93. Việc ~(i)sửa đổi cho khớp không phân biệt chữ hoa chữ thường dường như không tương thích với /hậu tố chỉ khớp với các thư mục (đây có thể là một lỗi trong bản phát hành ksh của tôi). Vì vậy, tôi sử dụng một chiến lược khác, để loại bỏ các thư mục không.

cd () {
  command cd "$@" 2>/dev/null && return
  typeset -a args; typeset previous target; typeset -i count=0
  args=("$@")
  for target in ~(Ni)"${args[$(($#-1))]}"; do
    [[ -d $target ]] || continue
    if ((count==1)); then printf "Ambiguous case-insensitive directory match:\n%s\n" "$previous" >&2; fi
    if ((count)); then echo "$target"; fi
    ((++count))
    previous=$target
  done
  ((count <= 1)) || return 3
  args[$(($#-1))]=$target
  command cd "${args[@]}"
}

Zsh

Cuối cùng, đây là phiên bản zsh. Một lần nữa, cho phép hoàn thành không phân biệt chữ hoa chữ thường có lẽ là lựa chọn tốt nhất. Cài đặt sau đây rơi trở lại toàn cầu không phân biệt chữ hoa chữ thường nếu không có trường hợp khớp chính xác:

zstyle ':completion:*' '' matcher-list 'm:{a-z}={A-Z}'

Xóa ''để hiển thị tất cả các kết quả khớp không phân biệt chữ hoa chữ thường ngay cả khi có khớp chính xác. Bạn có thể thiết lập điều này từ giao diện menu của compinstall.

cd () {
  builtin cd "$@" 2>/dev/null && return
  emulate -L zsh
  setopt local_options extended_glob
  local matches
  matches=( (#i)${(P)#}(N/) )
  case $#matches in
    0) # There is no match, even case-insensitively. Try cdpath.
      if ((#cdpath)) &&
         [[ ${(P)#} != (|.|..)/* ]] &&
         matches=( $^cdpath/(#i)${(P)#}(N/) ) &&
         ((#matches==1))
      then
        builtin cd $@[1,-2] $matches[1]
        return
      fi
      # Still nothing. Let cd display the error message.
      builtin cd "$@";;
    1)
      builtin cd $@[1,-2] $matches[1];;
    *)
      print -lr -- "Ambiguous case-insensitive directory match:" $matches >&2
      return 3;;
  esac
}

1
Điều đó thật tuyệt. Nhưng bạn sẽ cần thêm nó để inputrcnó hoạt động. Như thế này:echo "set completion-ignore-case on" >> ~/.inputrc
jsejcksn

@JesseJackson Vâng, điều đó được ngầm hiểu ở đây bởi vì người hỏi đã biết, nhưng tôi sẽ thêm nó vào câu trả lời của mình cho khách truy cập trong tương lai.
Gilles 'SO- ngừng trở nên xấu xa'

Tôi gặp lỗi sau khi thử sử dụng cd với điều này: cd:cd:17: no such file or directory: videos(Tôi có một thư mục được gọi Videos)
Sridhar Sarnobat

@ user7000 Phiên bản nào, dưới vỏ nào?
Gilles 'SO- ngừng trở nên xấu xa'

1
@ user7000 Hoạt động với tôi theo zsh 5.0.7. Có lẽ bạn đã đặt một tùy chọn thay đổi cách hoạt động của Globing? Nó có giúp gì nếu bạn đổi emulate -L zshsang emulate -LR zshkhông? (Bằng cách này tôi chỉ cố định một lỗi, mà cần phải có được emulate -L zsh, chứ không phải emulate zsh, nếu không nó sẽ lộn xộn lên tùy chọn shell của bạn.)
Gilles 'Somali dừng vốn là xấu'
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.