Як зробити так, щоб аргументи CD не були чутливими?


9

Іноді під час доступу до різних каталогів трапляється більшість випадків, коли я пам'ятаю імена або принаймні частину імен каталогу в нашій системі Linux. Але деякі каталоги названі, починаючи з перших символів або одного з символів у середині верхнього регістру імені.

Чи може хто-небудь підказати, як я можу зробити аргументи після cdкомандного випадку INSENSITIVE, таким чином, що якщо я виконую cd BackupDirectoryабо cd backupdirectoryвін міг би ввести ім'я каталогу BackupDirectory.

Звичайно, я не хочу вкручувати речі іншим користувачам, тому, якщо вищезазначене можливо, чи можливо, що зміна може бути застосована саме до сеансу, який я використовую, і не впливати на інших користувачів?

Добре, я спробував, set completion-ignore-caseале це просто не працює. Це просто допомагає в тому, що якщо я набираю cd bта / Tabабо Esc Escзаповнює ім'я каталогу, ігноруючи регістр. Але те, що мені потрібно, якщо я це роблю cd backupdirectory, він просто ігнорує справу і вступає BackupDirectoryсамостійно.


Як ти уникнеш двозначності? Якщо у вас є backUPі backUpяк би backupні, в який каталог ви хочете перейти?
Бернхард

Яку оболонку ви використовуєте?
Герт ван ден Берг

Чи обдумали ви використовувати такий інструмент, як mcперехід на графічний інтерфейс? Значно полегшує життя.
ott--

Відповіді:


17

Увімкнення cdspellдопоможе:

shopt -s cdspell

Зі manсторінки:

cdspell Якщо встановлено, незначні помилки в написанні компонента каталогу в команді cd будуть виправлені. Перевірені помилки - це переміщені символи, пропущений символ та один символ занадто багато. Якщо виправлення знайдено, виправлене ім'я файлу друкується, і команда продовжується. Цей варіант використовується лише інтерактивними оболонками.


Чи потрібно робити щось після виконання цієї команди, щоб зміна набрала чинності?
Натан Артур

Я би припустив це, тому що просто введення shopt -s cdspell для мене нічого не робить
sdfsdf

10

Баш

set completion-ignore-case onв ~/.inputrc(або bind 'set completion-ignore-case on'в ~/.bashrc) буде моєю рекомендацією. Якщо ви збираєтесь ввести повне ім’я, навіщо розмовляти кількома натисканнями Shiftклавіші?

Але якщо ви дійсно цього хочете, ось обгортка, cdяка намагається точно відповідати, а якщо такої немає, шукає збіг, що не враховує регістр, і виконує його, якщо він унікальний. Він використовує параметр nocaseglobоболонки для нечутливого до регістру глобалізації та перетворює аргумент у глобус шляхом додавання @()(що нічого не відповідає і не вимагає extglob). extglobОпція повинна бути включена при визначенні функції, в іншому випадку удар не може навіть розібрати його. Ця функція не підтримує 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
}

Кш

Поки я на це, ось подібна функція для ksh93. ~(i)Модифікована для випадку нечутливого відповідності здається несумісним з /суфіксом , щоб відповідати тільки каталогам (це може бути помилка в моєму випуску KSH). Тому я використовую іншу стратегію, щоб вилучити не-каталоги.

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. Знову ж таки, дозволити нечутливе до решти випадку, мабуть, найкращий варіант. Наступне налаштування повертається до нечутливого до глобалізації глобусу, якщо немає точного випадку відповідності:

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

Видаліть, ''щоб показати всі збіги, що не враховують регістри, навіть якщо є точний регістр відповідності. Ви можете встановити це в інтерфейсі меню 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
Це чудово. Але вам потрібно буде додати його, щоб inputrcвін працював. echo "set completion-ignore-case on" >> ~/.inputrc
Ось так

@JesseJackson Так, це тут малося на увазі, оскільки запитувач уже знав, але я додам це до своєї відповіді для майбутніх відвідувачів.
Жиль "ТАК - перестань бути злим"

При спробі використовувати компакт-диск із цим я отримую таку помилку: cd:cd:17: no such file or directory: videos(У мене є Videos
ректор, який

@ user7000 Яка версія, під якою оболонкою?
Жил 'ТАК - перестань бути злим'

1
@ user7000 працює для мене під zsh 5.0.7. Можливо, ви встановили варіант, який змінює спосіб роботи глобуса? Чи допоможе це, якщо ви перейдете emulate -L zshна emulate -LR zsh? (До речі, я щойно виправив помилку, яка повинна була бути emulate -L zsh, ні emulate zsh, інакше це зіпсує ваші варіанти оболонки.)
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.