때로는 다양한 디렉터리에 액세스할 때 대부분의 경우 내 Linux 시스템에 있는 디렉터리의 이름이나 적어도 일부 이름을 기억합니다. 그러나 일부 디렉터리의 이름은 첫 번째 문자를 대문자로 사용하거나 이름 중간에 대문자를 사용하여 지정됩니다.
명령을 실행하면 디렉터리 이름 BackupDirectory를 입력할 수 있도록 cd
명령 뒤에 있는 인수를 대소문자를 구분하지 않게 만드는 방법을 제안할 수 있는 사람이 있습니까?cd BackupDirectory
cd backupdirectory
물론 다른 사용자에게 문제를 일으키고 싶지 않기 때문에 위의 시나리오가 작동한다면 다른 사용자에게 영향을 주지 않고 내가 사용 중인 세션에만 변경 사항을 적용하는 것이 가능한가요?
네, 시도해 보았지만 set completion-ignore-case
작동하지 않습니다. 대소문자 cd b
를 무시하고 디렉토리 이름을 입력 Tab하거나 입력하는 경우 에만 도움이 됩니다 . Esc Esc그러나 내가 필요한 것은 을 수행하면 cd backupdirectory
대소문자를 무시하고 BackupDirectory
자체적으로 입력한다는 것입니다.
답변1
활성화하면 cdspell
도움이 됩니다.
shopt -s cdspell
man
페이지 에서 :
CD 철자법 설정된 경우 cd 명령의 디렉터리 구성 요소에서 사소한 오타를 수정합니다. 확인된 오류에는 뒤바뀐 문자, 누락된 문자, 한 문자가 너무 많음 등이 포함됩니다. 수정 사항이 발견되면 수정된 파일 이름이 인쇄되고 명령이 계속됩니다. 이 옵션은 대화형 쉘에서만 사용됩니다.
답변2
불다
set completion-ignore-case on
in ~/.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
홈 디렉터리에 추가하면 됩니다. 이것은 나에게도 효과적입니다. 도움이 되었기를 바랍니다.