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

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

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

任何人都可以建议我如何使cd命令 case 后面的参数不敏感,这样如果我执行cd BackupDirectorycd backupdirectory它可以输入目录名称 BackupDirectory。

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

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

答案1

启用cdspell将有助于:

shopt -s cdspell

man页面:

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

答案2

重击

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
}

克什

当我这样做时,这里有一个类似的 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的主目录中即可。这对我也有用。希望这可以帮助。

相关内容