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.