Jak sprawić, by argumenty cd nie rozróżniały wielkości liter?

9

Czasami podczas uzyskiwania dostępu do różnych katalogów zdarza się, że większość razy pamiętam nazwy lub przynajmniej część nazw katalogu w naszym systemie Linux. Ale niektóre katalogi są nazwane zaczynając od wielkich liter pierwszego znaku lub jednego ze znaków w środku nazwy Wielkie litery.

Czy ktoś może zasugerować, w jaki sposób mogę cdustawić argumenty występujące po poleceniu INSENSITIVE, na przykład, jeśli wykonam cd BackupDirectorylub cd backupdirectorymoże wprowadzić nazwę katalogu BackupDirectory.

Oczywiście nie chcę przekręcać tego innym użytkownikom, więc jeśli powyższe jest możliwe, czy to możliwe, że zmiana może zostać zastosowana tylko do sesji, z której korzystam i nie wpływa na innych użytkowników?

Ok, próbowałem, set completion-ignore-caseale to po prostu nie działa. To po prostu pomaga tym, że jeśli I typu cd bi Tabczy Esc Escwypełnia nazwę katalogu ignorując sprawę. Ale potrzebuję, jeśli to zrobię cd backupdirectory, to po prostu ignoruje sprawę i wchodzi BackupDirectorysamodzielnie.

Ankit Vashistha
źródło
Jak unikniesz dwuznaczności? Jeśli masz backUPi backUpjak backupmożesz nie przejść do katalogu, do którego chcesz przejść?
Bernhard
Jakiej powłoki używasz?
Gert van den Berg
Czy rozważałeś użycie narzędzia takiego jak mcprzejście na GUI? Ułatwia życie.
ott--

Odpowiedzi:

17

Włączenie cdspellpomoże:

shopt -s cdspell

Ze manstrony:

cdspell Jeśli jest ustawiony, drobne błędy w pisowni komponentu katalogu w poleceniu cd zostaną poprawione. Sprawdzane błędy to transponowane znaki, brakujący znak i jeden znak za dużo. Jeśli zostanie znaleziona poprawka, drukowana jest poprawiona nazwa pliku i polecenie jest kontynuowane. Ta opcja jest używana tylko przez interaktywne powłoki.

dogbane
źródło
Czy po wykonaniu tego polecenia musisz coś zrobić, aby zmiana zaczęła obowiązywać?
Nathan Arthur
Zakładałbym, że tak, ponieważ samo wejście do shopt -s cdspell nic dla mnie nie robi
sdfsdf
10

Grzmotnąć

set completion-ignore-case onw ~/.inputrc(lub bind 'set completion-ignore-case on'w ~/.bashrc) byłoby moją rekomendacją. Jeśli masz zamiar wpisać pełną nazwę, po co Shiftnaciskać kilka klawiszy?

Ale jeśli naprawdę tego chcesz, oto opakowanie, cdktóre próbuje dokładnie dopasować, a jeśli nie, szuka dopasowania bez rozróżniania wielkości liter i wykonuje je, jeśli jest unikalne. Używa nocaseglobopcji powłoki do globowania bez rozróżniania wielkości liter i zamienia argument w glob, dołączając @()(który nie pasuje do niczego i wymaga extglob). extglobOpcja musi być włączona przy definiowaniu funkcji, inaczej bash nie można nawet analizować je. Ta funkcja nie obsługuje 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

W tym momencie jest podobna funkcja dla ksh93. ~(i)Zmodyfikowane do uwzględniania wielkości liter dopasowywania wydaje się być niezgodne z /przyrostkiem, aby dopasować katalogów tylko (może to być błąd w moim wydaniu ksh). Dlatego używam innej strategii, aby usunąć nie-katalogi.

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

Wreszcie, oto wersja zsh. Ponownie, umożliwienie bez rozróżniania wielkości liter jest prawdopodobnie najlepszą opcją. Następujące ustawienie wraca do globowania bez rozróżniania wielkości liter, jeśli nie ma dopasowania dokładnego:

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

Usuń, ''aby wyświetlić wszystkie dopasowania bez rozróżniania wielkości liter, nawet jeśli istnieje dopasowanie dokładnie z uwzględnieniem wielkości liter. Możesz to ustawić w interfejsie 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
}
Gilles „SO- przestań być zły”
źródło
1
To jest świetne. Ale musisz go dodać inputrc, aby działał. W ten sposób:echo "set completion-ignore-case on" >> ~/.inputrc
jsejcksn
@JesseJackson Tak, to było niejawne, ponieważ pytający już wiedział, ale dodam to do mojej odpowiedzi dla przyszłych gości.
Gilles „SO- przestań być zły”
Dostaję następujący błąd podczas próby użycia cd z tym: cd:cd:17: no such file or directory: videos(mam dir o nazwie Videos)
Sridhar Sarnobat
@ user7000 Która wersja, pod jaką powłoką?
Gilles „SO- przestań być zły”
1
@ user7000 Działa dla mnie pod Zsh 5.0.7. Może ustawiłeś opcję, która zmienia sposób działania globowania? Czy to pomoże, jeśli zmienisz się emulate -L zshna emulate -LR zsh? (Nawiasem mówiąc, właśnie naprawiłem błąd, który powinien był być emulate -L zsh, nie emulate zsh, w przeciwnym razie zepsułby to twoje opcje powłoki.)
Gilles „SO- przestań być zły”