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

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
?

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
}

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.


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.


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
}

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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.