Como tornar os argumentos do cd maiúsculas e minúsculas INsensíveis?

9

Às vezes, ao acessar os vários diretórios, acontece na maioria das vezes que me lembro dos nomes ou pelo menos parte dos nomes de um diretório em nosso sistema Linux. Mas alguns dos diretórios são nomeados começando com maiúsculas de primeiro caractere ou um dos caracteres no meio do nome Maiúsculas.

Alguém pode sugerir como posso fazer os argumentos após o cdcaso do comando INSENSITIVE, de modo que, se eu executar cd BackupDirectoryou cd backupdirectorypuder digitar o nome do diretório BackupDirectory.

É claro que eu não quero estragar tudo para outros usuários. Se isso for possível, é possível que a alteração possa ser aplicada apenas à sessão que estou usando e não afete outros usuários?

Ok, eu tentei, set completion-ignore-casemas isso simplesmente não funciona. Apenas ajuda se eu digitar cd be / Tabou Esc Escpreencher o nome do diretório, ignorando o caso. Mas, o que eu preciso é que, se eu fizer um cd backupdirectory, simplesmente ignore o caso e entre BackupDirectorypor conta própria.

Ankit Vashistha
fonte
Como você evitará a ambiguidade? Se você possui backUPe backUp, como backupnão, para qual diretório deseja ir?
precisa
Qual shell você está usando?
Gert van den Berg
Você já pensou em usar uma ferramenta como mcou mudar para uma GUI? Torna a vida muito mais fácil.
ott--

Respostas:

17

A ativação cdspellajudará:

shopt -s cdspell

Na manpágina:

cdspell Se definido, erros menores na ortografia de um componente de diretório em um comando cd serão corrigidos. Os erros verificados são caracteres transpostos, um caractere ausente e um caractere a mais. Se uma correção for encontrada, o nome do arquivo corrigido será impresso e o comando prosseguirá. Esta opção é usada apenas por shells interativos.

dogbane
fonte
Você precisa fazer alguma coisa após executar este comando para que a alteração entre em vigor?
Nathan Arthur
Eu diria assim porque simplesmente digitando shopt -s cdspell não está fazendo nada para mim
sdfsdf
10

Bater

set completion-ignore-case onin ~/.inputrc(ou bind 'set completion-ignore-case on'in ~/.bashrc) seria minha recomendação. Se você deseja digitar o nome completo, por que recusar alguns toques na Shifttecla?

Mas se você realmente quiser, aqui está um wrapper cdque tenta uma correspondência exata e, se não houver, procura uma correspondência que não diferencia maiúsculas de minúsculas e a executa se for única. Ele usa a nocaseglobopção shell para globbing sem distinção entre maiúsculas e minúsculas e transforma o argumento em um globo acrescentando @()(que não corresponde a nada e requer extglob). A extglobopção precisa ser ativada ao definir a função, caso contrário, o bash não pode nem analisá-la. Esta função não suporta 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

Enquanto estou nisso, aqui está uma função semelhante para o ksh93. A ~(i)modificação modificada para correspondência sem distinção entre maiúsculas e minúsculas parece ser incompatível com o /sufixo para corresponder apenas aos diretórios (isso pode ser um bug no meu lançamento do ksh). Então, eu uso uma estratégia diferente, para eliminar não-diretórios.

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

Finalmente, aqui está uma versão zsh. Novamente, permitir a conclusão sem distinção entre maiúsculas e minúsculas é provavelmente a melhor opção. A configuração a seguir volta a globbing que não diferencia maiúsculas de minúsculas se não houver uma correspondência exata de maiúsculas e minúsculas:

zstyle ':completion:*' '' matcher-list 'm:{a-z}={A-Z}'

Remova ''para mostrar todas as correspondências que não diferenciam maiúsculas de minúsculas, mesmo que exista uma correspondência de maiúsculas e minúsculas. Você pode definir isso na interface do menu de 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
}
Gilles 'SO- parar de ser mau'
fonte
1
Isso é ótimo. Mas você precisará adicioná-lo para inputrcque ele funcione. Assim:echo "set completion-ignore-case on" >> ~/.inputrc
jsejcksn
@JesseJackson Sim, isso estava implícito aqui porque o autor da pergunta já sabia, mas vou adicioná-lo à minha resposta para futuros visitantes.
Gilles 'SO- stop be evil' (
Eu recebo o seguinte erro ao tentar usar o cd com isso: cd:cd:17: no such file or directory: videos(Eu tenho um dir chamado Videos) #
314 Sridhar Sarnobat 22/16/16
@ user7000 Qual versão, sob qual shell?
Gilles 'SO- stop be evil'
1
@ user7000 Funciona para mim no zsh 5.0.7. Talvez você tenha definido uma opção que muda a maneira como o globbing funciona? Ajuda se você mudar emulate -L zshpara emulate -LR zsh? (A propósito, eu apenas consertei um bug, isso deveria ter acontecido emulate -L zsh, emulate zshcaso contrário, isso prejudicaria suas opções de shell.)
Gilles 'SO- stop be evil'