如何使 cd 参数不区分大小写?

Ank*_*tha 10 shell bash cd-command

有时在访问各种目录时,大多数情况下我会记住我们 Linux 系统下目录的名称或至少部分名称。但是有些目录以第一个字符大写或名称中间的一个字符开始命名为大写。

任何人都可以建议我如何在cd命令 case INSENSITIVE之后设置参数,这样如果我执行cd BackupDirectorycd backupdirectory它可以输入目录名称 BackupDirectory。

当然,我不想为其他用户搞砸,所以如果上述是可能的,那么更改是否可能仅应用于我正在使用的会话而不影响其他用户?

好的,我试过了 set completion-ignore-case,但这不起作用。如果我输入cd b和/TabEsc Esc填充目录名称而忽略大小写,它只会有所帮助。但是,我需要的是,如果我执行 a cd backupdirectory,它只会忽略大小写并BackupDirectory自行进入。

dog*_*ane 18

启用cdspell将有助于:

shopt -s cdspell
Run Code Online (Sandbox Code Playgroud)

man页面:

cdspell 如果设置,cd 命令中目录组件拼写中的小错误将得到纠正。检查的错误包括转置字符、缺失字符和一个字符过多。如果找到更正,则打印更正后的文件名,然后命令继续执行。此选项仅由交互式 shell 使用。


Gil*_*il' 12

重击

set completion-ignore-case onin ~/.inputrc(或bind 'set completion-ignore-case on'in ~/.bashrc)将是我的建议。如果您要输入全名,为什么不按几下Shift键呢?

但是如果你真的想要它,这里有一个包装器,cd它尝试精确匹配,如果没有,则查找不区分大小写的匹配并在它唯一时执行它。它使用nocaseglobshell 选项进行不区分大小写的通配符@(),并通过附加(它不匹配任何内容,并且需要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
}
Run Code Online (Sandbox Code Playgroud)

克什

当我在做的时候,这里有一个类似的 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[@]}"
}
Run Code Online (Sandbox Code Playgroud)

Zsh

最后,这是一个 zsh 版本。同样,允许不区分大小写的完成可能是最好的选择。如果没有完全大小写匹配,以下设置将回退到不区分大小写的通配符:

zstyle ':completion:*' '' matcher-list 'm:{a-z}={A-Z}'
Run Code Online (Sandbox Code Playgroud)

删除''以显示所有不区分大小写的匹配项,即使存在完全大小写匹配项。您可以从 的菜单界面进行设置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
}
Run Code Online (Sandbox Code Playgroud)