有时,在访问各个目录时,大多数时候我都会记住 Linux 系统下目录的名称或至少部分名称。但有些目录的命名以第一个字符大写或名称中间的一个字符大写开头。
任何人都可以建议我如何使cd
命令 case 后面的参数不敏感,这样如果我执行cd BackupDirectory
或cd backupdirectory
它可以输入目录名称 BackupDirectory。
当然,我不想为其他用户搞砸事情,所以如果上述情况可行,是否有可能更改仅应用于我正在使用的会话而不影响其他用户?
好的,我尝试 set completion-ignore-case
过,但这不起作用。它只是有帮助,如果我输入cd b
and Tab/orEsc Esc它填充目录名称而忽略大小写。但是,我需要的是,如果我执行 a cd backupdirectory
,它只会忽略大小写并BackupDirectory
自行输入。
答案1
启用cdspell
将有助于:
shopt -s cdspell
从man
页面:
cd拼写 如果设置,将更正 cd 命令中目录组件的拼写小错误。检查的错误包括字符调换、字符丢失和一个字符过多。如果发现更正,则打印更正的文件名,然后命令继续。此选项仅由交互式 shell 使用。
答案2
重击
set completion-ignore-case on
in ~/.inputrc
(或bind 'set completion-ignore-case on'
in ~/.bashrc
) 将是我的建议。如果您要输入全名,为什么要犹豫按几下键呢Shift?
但如果您确实想要它,这里有一个包装器cd
,它尝试精确匹配,如果没有,则查找不区分大小写的匹配,如果唯一,则执行它。它使用nocaseglob
shell 选项进行不区分大小写的通配符,并通过附加将参数转换为通配符@()
(不匹配任何内容,并且需要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
的主目录中即可。这对我也有用。希望这可以帮助。