Come fare in modo che cd dir / nomefile mi porti a dir /?


10

Troverei molto comodo essere in grado di utilizzare cdcon un argomento file .

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

Quale sarebbe il miglior alias o funzione per raggiungere questo comportamento?

EDIT : Mi dispiace non l'ho menzionato in primo luogo: io usozsh

Risposte:


5

In zsh, spesso faccio:

cd /path/to/somefile(:h)

( hper head).

Se somefileè un collegamento simbolico, puoi anche fare:

cd somefile(:A:h)

Per raggiungere la directory in cui è possibile trovare la destinazione del collegamento simbolico.


L' zshequivalente dell'unica bashsoluzione di Chris sarebbe:

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

In zsh, puoi anche ridefinire quali "parole" Ctrl-Wrimuovono.

In zsh"parole" nel contesto dei widget di movimento / trasposizione / eliminazione basati su parole sono sequenze di allarmi più i caratteri nella $WORDCHARSvariabile che per impostazione predefinita include /.

È possibile rimuovere /in $WORDCHARSmodo da eliminare Ctrl-Wsolo un componente del percorso:

WORDCHARS=${WORDCHARS/\/}

Un'altra utile estensione è il select-word-stylewidget che è possibile utilizzare per scegliere in modo interattivo tra diversi stili di parole.

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

Quindi premendo Alt-Wpuoi scegliere tra diversi stili di parole.

$ 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
?

Interessante. (Uso anche zsh).
Sébastien,

Modifica molto interessante sul potere zshe sugli stili di parole. Grazie anche per il zshcomando. Fa perfettamente il lavoro.
Sébastien,

15

Presumo che desideri conservare la funzionalità originale se inserisci una directory e stai utilizzando bash.

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

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

Se non hai mai intenzione di usare le opzioni del cd ( -P, ecc.), Allora anche questo sarà sufficiente:

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

4
se cambi il nome della funzione in cd assicurati di aggiungere builtindavanti alle cdchiamate
Ulrich Dangel

@Chris: hai assunto bene;) Grazie per questa funzione pronta per l'uso
Sébastien,

La versione che conserva le cdopzioni non funziona zsh. Quello più semplice funziona bene zsh, MA cdnon è più equivalente come cd ~: /
Sébastien

@Sebastien Prova ora, penso che dovrebbe risolverlo.
Chris Down,

@Chris, in effetti è [ -z "$1" ]stato sufficiente aggiungere un controllo . Ho accettato la risposta di Stephane per darle maggiore visibilità, poiché sembra essere la soluzione migliore per zsh.
Sébastien,

7

È possibile utilizzare dirnameper rimuovere il nome file dal percorso, ad es

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

Vedere man dirname.


3
Si noti che se si immette una directory, questo cambierà nella directory sopra quella directory, che potrebbe non essere desiderata (non è chiaro dalla domanda se questo è desiderato o meno).
Chris Down,

1
@ChrisDown Vero, ma l'ho lasciato come un esercizio al lettore e la tua risposta mostra come gestirlo.
Adrian Frühwirth,

1
@ AdrianFrühwirth Un esercizio! Hah!

3

Se lo aggiungi al tuo .profile, quindi lo carichi ( source ~/.profileo esci e accedi di nuovo), mycd [file or directory]ti porterà nella directory giusta:

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

Se lo chiami cd, allora succederanno cose strane.


1
Ciò si interromperà se il nome della directory contiene spazi bianchi ed è necessario un punto e virgola di chiusura per terminare il gruppo di comandi. Modificato per te, spero non ti dispiaccia.
Chris Down,

@ChrisDown, anche se questo è vero per le altre shell, non è necessario il punto e virgola in chiusura zsh.
Stéphane Chazelas,

Inoltre, questo si interrompe se si passa a discutere cd, come -P.
Chris Down,

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
}

Data una directory chiamata $(sudo reboot), questa funzione potrebbe riavviare il sistema. Inoltre, l'utente sta utilizzando zsh, non bash.
Kusalananda

Dare qualsiasi comando $ (sudo reboot), questa funzione riavvierà il sistema. Inoltre, +1 non ho notato inizialmente "zsh" - buona cattura.
ecwpz91,

No, cd '$(sudo reboot)'cambierebbe directory, mentre la tua funzione proverebbe a valutare il nome.
Kusalananda

Ah, vedo e ho apportato modifiche. Fammi sapere se funziona? Buona pesca.
ecwpz91,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.