Jak zrobić `cd katalog / nazwa pliku` zabierze mnie do katalogu /?

10

Chciałbym znaleźć to bardzo wygodne, aby móc korzystać cdz plików argument.

cd myDirectory/anyname.anyExtension byłoby równoważne z cd myDirectory/

Jaki byłby najlepszy alias lub funkcja dla osiągnięcia tego zachowania?

EDYCJA : Przepraszam, że nie wspomniałem o tym na pierwszym miejscu: używamzsh

Sébastien
źródło

Odpowiedzi:

5

W zshczęsto robię:

cd /path/to/somefile(:h)

( hdla head).

Jeśli somefilejest dowiązaniem symbolicznym, możesz także:

cd somefile(:A:h)

Aby dostać się do katalogu, w którym można znaleźć cel dowiązania symbolicznego.


zshOdpowiednik Chris' teraz bashrozwiązanie -tylko byłoby:

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

W zsh, można również zmienić pojęcie „Słowa” Ctrl-WUsuwa.

W zsh„słowach” w kontekście widżetów ruchu / transpozycji / usuwania opartych na słowach są sekwencje alnum plus znaki w $WORDCHARSzmiennej, która domyślnie zawiera /.

Możesz usunąć /z, $WORDCHARSaby usunąć Ctrl-Wtylko jeden składnik ścieżki:

WORDCHARS=${WORDCHARS/\/}

Innym przydatnym rozszerzeniem jest select-word-stylewidget, którego można używać do interaktywnego wybierania różnych stylów słów.

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

Następnie naciśnięcie Alt-Wpozwala wybrać pomiędzy różnymi stylami słów.

$ 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
?
Stéphane Chazelas
źródło
Ciekawy. (Ja też używam zsh).
Sébastien
Bardzo interesująca edycja dotycząca mocy zshi stylów słów. Dziękuję również za zshpolecenie. Doskonale spełnia swoje zadanie.
Sébastien
16

Zakładam, że nadal chcesz zachować oryginalną funkcjonalność, jeśli wpiszesz katalog i korzystasz z niego bash.

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

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

Jeśli nigdy nie będziesz używać opcji cd ( -Pitp.), To wystarczy:

cd() { 
    if [ -d "$1" ] || [ -z "$1" ]; then
        builtin cd "$@"
    else
        builtin cd "${1%/*}"
    fi
}
Chris Down
źródło
4
jeśli zmienisz nazwę funkcji na cd, pamiętaj, aby dodać builtinprzed cdwywołaniami
Ulrich Dangel
@Chris: Masz rację;) Dzięki za tę gotową do użycia funkcję
Sébastien
Wersja zachowująca cdopcje nie działa zsh. Prostszy z tym działa dobrze zsh, ALE cdnie jest już równoważny z cd ~: /
Sébastien
@Sebastien Spróbuj teraz, myślę, że to powinno to naprawić.
Chris Down
@Chris, w rzeczy samej [ -z "$1" ]wystarczyło dodać czek . Zaakceptowałem odpowiedź Stephane'a, aby dać jej lepszą widoczność, ponieważ wydaje się to najlepszym rozwiązaniem zsh.
Sébastien
7

Możesz użyć dirnamedo usunięcia nazwy pliku ze ścieżki, np

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

Zobaczyć man dirname.

Adrian Frühwirth
źródło
3
Zauważ, że jeśli wpiszesz katalog, zmieni się on na katalog powyżej tego katalogu, co może nie być pożądane (nie jest jasne, czy jest to pożądane, czy nie).
Chris Down
1
@ChrisDown Prawda, ale zostawiłem to jako ćwiczenie czytelnikowi, a twoja odpowiedź pokazuje, jak sobie z tym poradzić.
Adrian Frühwirth
1
@ AdrianFrühwirth Ćwiczenie! Hah!
3

Jeśli dodasz to do swojego .profile, a następnie załaduj ( source ~/.profilelub wyloguj się i zaloguj ponownie), mycd [file or directory]przeniesie Cię do odpowiedniego katalogu:

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

Jeśli to cdnazwiesz, zdarzają się dziwne rzeczy.

jwhitlock
źródło
1
Spowoduje to uszkodzenie, jeśli nazwa katalogu zawiera spacje, a do zakończenia grupy poleceń potrzebny będzie średnik zamykający. Edytowałem to dla ciebie, mam nadzieję, że nie masz nic przeciwko.
Chris Down,
@ChrisDown, chociaż dotyczy to innych powłok, nie potrzebujesz średnika zamykającego zsh.
Stéphane Chazelas
To również się psuje, jeśli przekazujesz argumenty cd, na przykład -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
}
ecwpz91
źródło
Biorąc pod uwagę katalog o nazwie $(sudo reboot), funkcja ta może ponownie uruchomić system. Ponadto użytkownik korzysta zsh, a nie bash.
Kusalananda
Podaj dowolną komendę $ (sudo reboot), ta funkcja uruchomi ponownie system. Poza tym +1 początkowo nie zauważyłem „zsh” - dobry chwyt.
ecwpz91
Nie, cd '$(sudo reboot)'zmieniłbym katalog, a twoja funkcja spróbowałaby ocenić nazwę.
Kusalananda
Ach, widzę i wprowadziłem zmiany. Daj mi znać, czy działa? Dobry chwyt
ecwpz91,