Bagaimana cara membuat argumen argumen CD tidak sensitif?


9

Kadang-kadang ketika mengakses berbagai direktori itu terjadi sebagian besar waktu saya mengingat nama-nama atau setidaknya sebagian dari nama-nama direktori di bawah sistem Linux kami. Tetapi beberapa direktori diberi nama dimulai dengan huruf pertama atau salah satu karakter di tengah nama Huruf besar.

Adakah yang bisa menyarankan bagaimana saya bisa membuat argumen berikut cdperintah case INSENSITIVE, sehingga jika saya melakukan cd BackupDirectoryatau cd backupdirectorybisa memasukkan nama direktori BackupDirectory.

Tentu saja saya tidak ingin mengacaukan hal-hal untuk pengguna lain jadi jika hal di atas memungkinkan, apakah mungkin perubahan itu dapat diterapkan hanya pada sesi yang saya gunakan dan tidak mempengaruhi pengguna lain?

Oke, saya sudah mencoba set completion-ignore-casetetapi ini tidak berhasil. Ini hanya membantu jika saya mengetik cd bdan Tabatau Esc Escmengisi nama direktori dengan mengabaikan case. Tapi, yang saya butuhkan adalah jika saya melakukan cd backupdirectory, itu hanya mengabaikan kasus dan masuk BackupDirectorysendiri.


Bagaimana Anda menghindari ambiguitas? Jika sudah backUPdan backUp, bagaimana backuptidak ke direktori mana yang ingin Anda tuju?
Bernhard

Shell mana yang Anda gunakan?
Gert van den Berg

Sudahkah Anda mempertimbangkan untuk menggunakan alat seperti mcatau beralih ke GUI? Membuat hidup lebih mudah.
ott--

Jawaban:


17

Mengaktifkan cdspellakan membantu:

shopt -s cdspell

Dari manhalaman:

cdspell Jika diatur, kesalahan kecil dalam pengejaan komponen direktori dalam perintah cd akan diperbaiki. Kesalahan yang diperiksa adalah karakter yang dipindahkan, karakter yang hilang, dan satu karakter terlalu banyak. Jika koreksi ditemukan, nama file yang diperbaiki dicetak, dan perintah mulai. Opsi ini hanya digunakan oleh shell interaktif.


Apakah Anda harus melakukan sesuatu setelah menjalankan perintah ini agar perubahan berlaku?
Nathan Arthur

Saya berasumsi demikian karena hanya memasukkan shopt -s cdspell tidak melakukan apa-apa untuk saya
sdfsdf

10

Pesta

set completion-ignore-case ondi ~/.inputrc(atau bind 'set completion-ignore-case on'dalam ~/.bashrc) akan menjadi rekomendasi saya. Jika Anda akan mengetikkan nama lengkap, mengapa menolak keras pada beberapa penekanan Shifttombol?

Tetapi jika Anda benar-benar menginginkannya, ini adalah pembungkus cdyang mencoba untuk pertandingan yang tepat, dan jika tidak ada, cari pertandingan yang tidak peka terhadap huruf besar dan lakukan jika itu unik. Ia menggunakan nocaseglobopsi shell untuk globbing case-insensitive, dan mengubah argumen menjadi glob dengan menambahkan @()(yang tidak cocok dengan apa pun, dan mengharuskan extglob). The extglobpilihan harus diaktifkan ketika mendefinisikan fungsi, jika pesta bahkan tidak bisa mengurai itu. Fungsi ini tidak mendukung 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

Sementara saya melakukannya, inilah fungsi serupa untuk ksh93. The ~(i)dimodifikasi untuk kasus-sensitif pencocokan tampaknya tidak sesuai dengan /akhiran untuk mencocokkan direktori hanya (ini mungkin bug di rilis saya ksh). Jadi saya menggunakan strategi yang berbeda, untuk menyingkirkan non-direktori.

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

Akhirnya, inilah versi zsh. Sekali lagi, membiarkan penyelesaian case-insensitive mungkin merupakan pilihan terbaik. Pengaturan berikut akan kembali ke penggumpalan case-sensitive jika tidak ada kecocokan case-persis:

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

Hapus ''untuk menampilkan semua kecocokan dengan huruf besar-kecil sekalipun ada kecocokan dengan huruf besar-kecil. Anda dapat mengatur ini dari antarmuka menu 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
Ini bagus. Tetapi Anda harus menambahkannya inputrcagar berfungsi. Seperti ini:echo "set completion-ignore-case on" >> ~/.inputrc
jsejcksn

@JesseJackson Ya, itu tersirat di sini karena penanya sudah tahu, tapi saya akan menambahkannya ke jawaban saya untuk pengunjung masa depan.
Gilles 'SANGAT berhenti menjadi jahat'

Saya mendapatkan kesalahan berikut ketika mencoba menggunakan cd dengan ini: cd:cd:17: no such file or directory: videos(Saya punya dir disebut Videos)
Sridhar Sarnobat

@ user7000 Versi mana, di bawah cangkang mana?
Gilles 'SANGAT berhenti menjadi jahat'

1
@ user7000 Bekerja untuk saya di bawah zsh 5.0.7. Mungkin Anda telah menetapkan opsi yang mengubah cara kerja globbing? Apakah itu membantu jika Anda mengubah emulate -L zshke emulate -LR zsh? (Ngomong-ngomong, aku baru saja memperbaiki bug, yang seharusnya emulate -L zsh, bukan emulate zsh, kalau tidak itu akan mengacaukan opsi shell kamu.)
Gilles 'SO-stop being evil'
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.