CDパラメータで大文字と小文字を区別しないようにする方法は?

CDパラメータで大文字と小文字を区別しないようにする方法は?

時には、さまざまなディレクトリにアクセスするとき、ほとんどの場合、私のLinuxシステム上のディレクトリの名前または少なくともいくつかの名前を覚えています。ただし、一部のディレクトリの名前は、最初の文字を大文字として使用するか、名前の途中で大文字を使用して指定します。

コマンドを実行すると、ディレクトリ名BackupDirectoryを入力できるように、コマンドcdの後にある引数を大文字と小文字を区別しないようにする方法を提案できる人はいますか?cd BackupDirectorycd backupdirectory

もちろん、他のユーザーに問題を引き起こしたくないので、上記のシナリオが機能している場合は、他のユーザーに影響を与えず、私が使用しているセッションにのみ変更を適用することは可能ですか?

はい、試してみましたが動作 set completion-ignore-caseしません。大文字と小文字cd bを無視してディレクトリ名を入力Tabまたは入力する場合にのみ役立ちます。Esc Escしかし、私が必要とするのは、これを行うとcd backupdirectory大文字と小文字を無視してBackupDirectory自分で入力することです。

答え1

有効にするとcdspell役立ちます。

shopt -s cdspell

manページから:

CDスペル 設定されている場合は、cdコマンドのディレクトリコンポーネントでマイナーなミスを修正します。確認されたエラーには、反転文字、欠落文字、1文字が多すぎるなどが含まれます。修正が見つかると、変更されたファイル名が印刷され、コマンドが続行されます。このオプションは対話型シェルでのみ使用されます。

答え2

吹く

set completion-ignore-case onin ~/.inputrc(またはbind 'set completion-ignore-case on'in ~/.bashrc)が私の提案になります。名前を入力するには、いくつかのキーを押すのを躊躇するのはなぜですかShift

しかし、本当にしたいcd場合は、正確な一致を試み、そうでない場合は大文字と小文字を区別しない一致を見つけて、一意の場合に実行するラッパーがあります。nocaseglob大文字と小文字を区別しないワイルドカードのシェルオプションを使用し、引数を追加してワイルドカードに変換します@()(何も一致せず、必須extglob)。extglobこのオプションは、関数を定義するときにオンにする必要があります。それ以外の場合、bashはそれを解析することもできません。この機能はサポートされていません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
}

答え3

zshコマンドを実行して期待した結果が得られたからです。

compctl -M '' 'm:{a-zA-Z}={A-Za-z}'

cdこれを行った後、名前と同じ大文字と小文字を使用せずにディレクトリに入ることができました。

セッションだけでなく永続的に保存するには、.zprofileホームディレクトリに追加するだけです。これは私にとっても効果的です。お役に立てば幸いです。

関連情報