web-dev-qa-db-ja.com

CD引数の大文字と小文字を区別しないようにするにはどうすればよいですか?

さまざまなディレクトリにアクセスしているときに、Linuxシステムのディレクトリの名前または少なくとも一部の名前を覚えていることがよくあります。ただし、一部のディレクトリは、最初の文字の大文字、または大文字の名前の真ん中にある文字の1つで始まる名前が付けられています。

cd BackupDirectoryまたはcd backupdirectoryを実行すると、ディレクトリ名BackupDirectoryを入力できるように、cdコマンドケースINSENSITIVEに従って引数を作成する方法を誰かが提案できますか?.

もちろん、私は他のユーザーのために物事を台無しにしたくないので、上記が可能であれば、変更は私が使用しているセッションにのみ適用され、他のユーザーには影響しない可能性はありますか?

はい、set completion-ignore-caseを試してみましたが、うまくいきません。 cd bと入力して、 Tab または EscEsc 大文字と小文字を区別せずにディレクトリ名を入力します。ただし、cd backupdirectoryを実行すると、大文字と小文字が無視され、BackupDirectoryが単独で入力されます。

9
Ankit Vashistha

cdspellを有効にすると、次のことが役立ちます。

shopt -s cdspell

manページから:

cdspell設定すると、cdコマンドのディレクトリコンポーネントのスペルの小さなエラーが修正されます。チェックされるエラーは、転置文字、欠落文字、1文字多すぎです。修正が見つかると、修正されたファイル名が出力され、コマンドが続行されます。このオプションは対話型シェルでのみ使用されます。

17
dogbane

Bash

_set completion-ignore-case on_の_~/.inputrc_(または_bind 'set completion-ignore-case on'_の_~/.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
}
_

Ksh

その間、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

最後に、これが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
}
_