Wie mache ich CD-Argumente unempfindlich?

9

Manchmal erinnere ich mich beim Zugriff auf die verschiedenen Verzeichnisse meistens an die Namen oder zumindest einen Teil der Namen eines Verzeichnisses unter unserem Linux-System. Einige der Verzeichnisse werden jedoch beginnend mit Großbuchstaben oder einem der Zeichen in der Mitte des Namens Großbuchstaben benannt.

Kann jemand vorschlagen, wie ich die Argumente nach dem cdBefehl case INSENSITIVE machen kann, so dass, wenn ich ausführe cd BackupDirectoryoder cd backupdirectoryes den Verzeichnisnamen BackupDirectory eingeben könnte.

Natürlich möchte ich die Dinge nicht für andere Benutzer vermasseln. Wenn dies möglich ist, ist es dann möglich, dass die Änderung nur auf die von mir verwendete Sitzung angewendet wird und keine Auswirkungen auf andere Benutzer hat?

Ok, ich habe es anprobiert, set completion-ignore-caseaber das funktioniert einfach nicht. Es hilft nur dabei, wenn ich tippe cd bund / Taboder Esc Escden Verzeichnisnamen ausfülle, wobei der Fall ignoriert wird. Aber was ich brauche, ist, wenn ich a mache cd backupdirectory, es ignoriert einfach den Fall und tritt BackupDirectoryvon selbst ein.

Ankit Vashistha
quelle
Wie vermeiden Sie Mehrdeutigkeiten? Wenn Sie backUPund haben backUp, wie würde backupnein zu welchem ​​Verzeichnis Sie gehen möchten?
Bernhard
Welche Shell benutzt du?
Gert van den Berg
Haben Sie darüber nachgedacht, ein Tool wie zu verwenden mcoder zu einer GUI zu wechseln? Macht das Leben viel einfacher.
ott--

Antworten:

17

Das Aktivieren cdspellhilft:

shopt -s cdspell

Von der manSeite:

cdspell Wenn gesetzt, werden kleinere Fehler in der Rechtschreibung einer Verzeichniskomponente in einem cd-Befehl korrigiert. Die überprüften Fehler sind transponierte Zeichen, ein fehlendes Zeichen und ein Zeichen zu viele. Wenn eine Korrektur gefunden wird, wird der korrigierte Dateiname gedruckt und der Befehl fortgesetzt. Diese Option wird nur von interaktiven Shells verwendet.

Dogbane
quelle
Müssen Sie nach dem Ausführen dieses Befehls etwas tun, damit die Änderung wirksam wird?
Nathan Arthur
Ich würde das annehmen, weil die einfache Eingabe von shopt -s cdspell nichts für mich bedeutet
sdfsdf
10

Bash

set completion-ignore-case onin ~/.inputrc(oder bind 'set completion-ignore-case on'in ~/.bashrc) wäre meine Empfehlung. Wenn Sie den vollständigen Namen eingeben möchten, warum sollten Sie dann ein paar ShiftTastendrücke ausführen ?

Aber wenn Sie es wirklich wollen, finden Sie hier einen Wrapper cd, der nach einer genauen Übereinstimmung sucht. Wenn es keine gibt, sucht er nach einer Übereinstimmung ohne Berücksichtigung der Groß- und Kleinschreibung und führt sie aus, wenn sie eindeutig ist. Es verwendet die nocaseglobShell-Option für das Globbing ohne Berücksichtigung der Groß- und Kleinschreibung und verwandelt das Argument durch Anhängen in einen Glob @()(der mit nichts übereinstimmt und erforderlich ist extglob). Die extglobOption muss beim Definieren der Funktion aktiviert sein, andernfalls kann bash sie nicht einmal analysieren. Diese Funktion wird nicht unterstützt 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ährend ich gerade dabei bin, ist hier eine ähnliche Funktion für ksh93. Das ~(i)für Übereinstimmungen ohne Berücksichtigung der Groß- und Kleinschreibung modifizierte Element scheint nicht mit dem /Suffix kompatibel zu sein, nur Verzeichnisse abzugleichen (dies kann ein Fehler in meiner Version von ksh sein). Daher verwende ich eine andere Strategie, um Nicht-Verzeichnisse auszusortieren.

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

Zum Schluss noch eine zsh-Version. Auch hier ist es wahrscheinlich die beste Option, die Vervollständigung ohne Berücksichtigung der Groß- und Kleinschreibung zuzulassen. Die folgende Einstellung greift auf Globbing ohne Berücksichtigung der Groß- und Kleinschreibung zurück, wenn keine Übereinstimmung mit der Groß- und Kleinschreibung vorliegt:

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

Entfernen Sie ''diese Option , um alle Übereinstimmungen ohne Berücksichtigung der Groß- und Kleinschreibung anzuzeigen, auch wenn eine Übereinstimmung mit der Groß- und Kleinschreibung vorliegt. Sie können dies über die Menüoberfläche von einstellen 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 - hör auf böse zu sein'
quelle
1
Das ist toll. Sie müssen es jedoch hinzufügen, inputrcdamit es funktioniert. So:echo "set completion-ignore-case on" >> ~/.inputrc
jsejcksn
@JesseJackson Ja, das war hier implizit, weil der Fragesteller es bereits wusste, aber ich werde es meiner Antwort für zukünftige Besucher hinzufügen.
Gilles 'SO - hör auf böse zu sein'
Ich erhalte die folgende Fehlermeldung, wenn ich versuche, eine CD damit zu verwenden: cd:cd:17: no such file or directory: videos(Ich habe ein Videos
Verzeichnis
@ user7000 Welche Version, unter welcher Shell?
Gilles 'SO - hör auf böse zu sein'
1
@ user7000 Funktioniert für mich unter zsh 5.0.7. Vielleicht haben Sie eine Option festgelegt, die die Funktionsweise von Globbing ändert? Hilft es , wenn Sie ändern emulate -L zshzu emulate -LR zsh? (Übrigens habe ich gerade einen Fehler behoben, der eigentlich hätte sein emulate -L zshsollen emulate zsh, sonst würde es Ihre Shell-Optionen durcheinander bringen.)
Gilles 'SO - hör auf böse