Como fazer 'cd dir / filename' me leva para dir /?

8

Eu consideraria muito conveniente poder usar cd com um argumento arquivo .

cd myDirectory/anyname.anyExtension seria equivalente a cd myDirectory/

Qual seria o melhor alias ou função para alcançar esse comportamento?

EDITAR : Desculpe eu não mencionei no 1º lugar: eu uso zsh

    
por Sébastien 17.05.2013 / 18:39

5 respostas

5

Em zsh , geralmente faço:

cd /path/to/somefile(:h)

( h para head ).

Se somefile for um link simbólico, você também pode fazer:

cd somefile(:A:h)

Para chegar ao diretório em que o destino do symlink pode ser encontrado.

O zsh equivalente da solução de Chris 'agora bash -only seria:

cd() {
  [[ ! -e $argv[-1] ]] || [[ -d $argv[-1] ]] || argv[-1]=${argv[-1]%/*}
  builtin cd "$@"
}

Em zsh , você também pode redefinir o que as "palavras" Ctrl-W eliminam.

Em zsh , "palavras" no contexto dos widgets de movimento / transposição / exclusão baseados em palavras são sequências de alnums mais os caracteres na variável $WORDCHARS , que por padrão inclui / .

Você pode remover / de $WORDCHARS para que Ctrl-W exclua apenas um componente do caminho:

WORDCHARS=${WORDCHARS/\/}

Outra extensão útil é o widget select-word-style , que você pode usar para escolher interativamente entre diferentes estilos de palavras.

autoload select-word-style
zle -N select-word-style
bindkey '\ew' select-word-style

Em seguida, pressionar Alt-W permite escolher entre diferentes estilos de palavras.

$ cd /blah/blih<Alt-W>
Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?
    
por 17.05.2013 / 20:14
15

Suponho que você ainda deseja manter a funcionalidade original se inserir um diretório e estiver usando bash .

cd() {
    local file="${!#}"

    if (( "$#" )) && ! [[ -d "$file" ]]; then
        builtin cd "${@:1:($#-1)}" "${file%/*}"
    else
        builtin cd "$@"
    fi
}

Se você nunca usará as opções do cd ( -P , etc), isso também será suficiente:

cd() { 
    if [ -d "$1" ] || [ -z "$1" ]; then
        builtin cd "$@"
    else
        builtin cd "${1%/*}"
    fi
}
    
por 17.05.2013 / 19:07
7

Você pode usar dirname para remover o nome do arquivo do caminho, por exemplo,

mycd() { cd "$(dirname "$1")"; }

Veja man dirname .

    
por 17.05.2013 / 18:44
3

Se você adicionar isso ao seu .profile , carregá-lo ( source ~/.profile ou sair e efetuar login novamente), então mycd [file or directory] o levará para o diretório correto:

mycd() { if [ -d "$1" ]; then cd "$1"; else cd "$( dirname "$1" )"; fi ; }

Se você nomear cd , então coisas estranhas acontecerão.

    
por 17.05.2013 / 19:13
0
cd2() {
 arg=() dir= cmd= IFS=" " msg='[-L|[-P [-e]]|-h] [dir|file]'

 while [ "$#" -gt 1 ] ; do
  case "$1" in
   -h) printf "%s: cd2 %s\n" "$0" "$msg"
    return 1 ;;
   *) arg+=("$1") ;;
  esac
  shift
 done

 [ -f "${1:-}" ] && dir="$(dirname ${1:-})" || dir="${1:A}"
 [ ! -z "$arg" ] && cmd="cd ${arg[@]} $dir" || cmd="cd $dir"

 if ! $cmd 2>/dev/null; then
  printf "%s: cd2 %s\n" "$0" "$msg"
  return 1
 fi
}
    
por 02.12.2018 / 02:27