Jak zarządzać długimi ścieżkami w Bash?

Mam problem z zarządzaniem długimi ścieżkami. Jak mogę szybko dostać się do takich ścieżek jak

/Users/User/.../.../.../.../.../Dev/C/card.c

I tried an alias

alias cd C='cd /Users/User/.../.../.../.../.../Dev/C'

Ale nie jestem w stanie zrobić aliasów dla dwóch oddzielnych słów. Mam długie listy aliasów i ścieżek Basha w CDPATH, więc waham się, czy zrobić je więcej. Jak zarządzać długimi ścieżkami?

[pomysły na Odpowiedzi]

Odpowiedź użytkownika litb ujawniła niektóre z moich problemów w zarządzaniu. Rzeczy, np. "CTRL + R","!-3:1: 2: 4: x " i " przyrostowe Szukaj", są dla mnie trudne. Prawdopodobnie pomagają w nawigacji po długich katalogach i w tym sensie zarządzaniu.

 8
Author: Masi, 2009-03-22

17 answers

Rozważ użycie dowiązań symbolicznych. Mam katalog ~/work/, w którym umieszczam dowiązania symboliczne do wszystkich moich aktualnych projektów.

Można również użyć zmiennych powłoki:

c='/Users/User/.../.../.../.../.../Dev/C'

Wtedy:

cd "$c"
 24
Author: Juliano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-24 11:45:56

Użycie dowiązań symbolicznych jest prawdopodobnie najlepszym pomysłem; ale możesz to zrobić jeszcze łatwiej niż wrzucenie ich wszystkich do katalogu domowego.

Jak już wspomniałeś, BASH ma funkcję o nazwie CDPATH , która jest tutaj bardzo przydatna.

Po prostu stwórz ukryty folder w swoim homedir (aby nie zaśmiecał twojego homedir zbytnio):

$ mkdir ~/.paths
$ cd ~/.paths
$ ln -s /my/very/long/path/name/to/my/project project
$ ln -s /some/other/very/long/path/to/my/backups backups
$ echo 'CDPATH=~/.paths' >> ~/.bashrc
$ source ~/.bashrc

To tworzy katalog w Twoim homedir o nazwie".paths", który zawiera dowiązania symboliczne do wszystkich długich lokalizacji katalogów, które regularnie use, a następnie ustawia zmienną CDPATH bash do tego katalogu (w Twoim .bashrc) i ponownie czyta .plik bashrc.

Teraz możesz przejść do każdej z tych ścieżek z gdziekolwiek :

$ cd project
$ cd backups

Pozostawiając ci krótką ścieżkę CD, bez zaśmiecających aliasów, a co ważniejsze: naprawdę łatwy sposób na nawigację do długich ścieżek z innych aplikacji, takich jak aplikacje UI, po prostu wchodząc w ~/.ścieżki lub dodanie tego katalogu do paska bocznego aplikacji UI lub więc.

Prawdopodobnie najprostsze wszechstronne rozwiązanie, jakie możesz mieć.

 32
Author: lhunath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-25 23:29:46

Utwórz dowiązania symboliczne w katalogu domowym (lub w innym wybranym przez Ciebie miejscu)

ln -s longDirectoryPath ~ / MySymLinkName

Zobacz man ln Po Więcej Szczegółów.

 6
Author: Dan Breslau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-03 19:57:59

Prawdopodobnie najprostszym rozwiązaniem jest użycie:

alias cdc='cd /Users/User/.../.../.../.../.../Dev/C'
alias cdbin='cd /Users/User/.../.../.../.../.../Dev/bin'
alias cdtst='cd /Users/User/.../.../.../.../.../Dev/tst'

Jeśli naprawdę pracujesz tylko nad jednym projektem na raz. Jeśli pracujesz nad wieloma projektami, możesz mieć inny alias, który zmienił katalogi w tych aliasach powyżej.

Więc użyłbyś czegoś w stylu:

proj game17
cdc
make
proj roman_numerals
cdbin
rm -f *
proj game17 ; cdc

Ponieważ jest to przydatna rzecz, postanowiłem złożyć serię skryptów, które mogą być używane. Wszystkie są oparte na pliku konfiguracyjnym umieszczonym w katalogu domowym, wraz z aliasami do skryptów źródłowych. Plik "~/.cdx_data" ma postać:

scrabble:top=~/dev/scrabble
scrabble:src=~/dev/scrabble/src
scrabble:bin=~/dev/scrabble/bin

sudoku:top=~/dev/scrabble
sudoku:src=~/dev/scrabble/src
sudoku:bin=~/dev/scrabble/bin
sudoku:data=~/dev/scrabble/data

I listuje wszystkie odpowiednie projekty (w tym przypadku Scrabble i sodoku) i ich katalogi (które mogą być różne dla każdego projektu, ale mają top, bin, src i dane w tym przykładzie).

Pierwszą czynnością jest inicjalizacja rzeczy, więc wpisz:

. ~/.cdx_init
Na końcu twojego .bash_profile i utwórz plik "~/.cdx_init" jako:
alias cdxl='. ~/.cdx_list'
alias projl='. ~/.cdx_projlist'
alias cdx='. ~/.cdx_goto'
alias proj='. ~/.cdx_proj'

To ustawia cztery aliasy do źródła plików, które Dołączę poniżej. Użycie to:

cdxl     - List all directories in current project.

projl    - List all projects.

proj     - Show current project.
proj <p> - Set current project to <p> (if allowed).

cdx      - Show current project/directory and expected/actual real
           directory, since they can get out of sync if you mix cd and cdx.
cdx .    - Set actual real directory to expected directory (in other words,
           get them back into sync).
cdx <d>  - Set directory to <d> (if allowed).

Rzeczywisty skrypt następuje. Po pierwsze, ".cdx_list" który wyświetla listę dozwolonych katalogów w bieżącym projekcie (potoki są podzielone na wiele linii dla czytelności, ale wszystkie powinny znajdować się w jednej linii).

echo "Possible directories are:"
cat ~/.cdx_data
    | grep "^${CDX_PROJ}:"
    | sed -e 's/^.*://' -e 's/=.*$//'
    | sort -u
    | sed 's/^/    /'

Podobnie, ".cdx_projlist" pokazuje wszystkie możliwe projekty:

echo "Possible projects are:"
cat ~/.cdx_data
    | grep ':'
    | sed 's/:.*$//'
    | sort -u
    | sed 's/^/    /'

W skryptach mięsnych, ".cdx_proj" ustawia i / lub pokazuje bieżący projekt:

if [[ "$1" != "" ]] ; then
    grep "^$1:" ~/.cdx_data >/dev/null 2>&1
    if [[ $? != 0 ]] ; then
        echo "No project name '$1'."
        projl
    else
        export CDX_PROJ="$1"
    fi
fi
echo "Current project is: [${CDX_PROJ}]"

I ".cdx_goto" jest to samo dla katalogów w obrębie projekt:

if [[ "$1" == "." ]] ; then
    CDX_TMP="${CDX_DIR}"
else
    CDX_TMP="$1"
fi
if [[ "${CDX_TMP}" != "" ]] ; then
    grep "^${CDX_PROJ}:${CDX_TMP}=" ~/.cdx_data >/dev/null 2>&1
    if [[ $? != 0 ]] ; then
            echo "No directory name '${CDX_TMP}' for project '${CDX_PROJ}'."
            cdxl
    else
            export CDX_DIR="${CDX_TMP}"
            cd $(grep "^${CDX_PROJ}:${CDX_DIR}=" ~/.cdx_data
                | sed 's/^.*=//'
                | head -1
                | sed "s:^~:$HOME:")
    fi
fi
CDX_TMP=$(grep "^${CDX_PROJ}:${CDX_DIR}=" ~/.cdx_data
    | sed 's/^.*=//'
    | head -1
    | sed "s:^~:$HOME:")
echo "Current project   is: [${CDX_PROJ}]"
echo "Current directory is: [${CDX_DIR}]"
echo "                      [${CDX_TMP}]"
echo "Actual  directory is: [${PWD}]"
unset CDX_TMP

Używa trzech zmiennych środowiskowych, które są zarezerwowane na własny użytek: "CDX_PROJ", "CDX_DIR" i "CDX_TMP". Poza tymi i wyżej wymienionymi plikami i aliasami nie są używane żadne inne zasoby. To najprostsze, ale najbardziej elastyczne rozwiązanie, jakie mogłem wymyślić. Powodzenia.

 5
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-26 05:32:23

Revisiting. Dzisiaj otrzymałem ten link z serwisu social bookmarking, a następnie od razu przypomniałem sobie to pytanie:

Nawigacja z bm

Zachowujemy proste, zwykłe zakładki tekstowe pliku i użyj narzędzia o nazwie bm do poszukiwania. Narzędzie może być również służy do edycji indeksu zakładek dynamicznie jak pokazano poniżej gdzie dodaj katalogi z poprzedniego przykład do indeksu.

 4
Author: Juliano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-02 16:41:22

Raz cd ' w tak długim katalogu, mam to w historii. Następnie wpisuję Ctrl-R dla wiersza "(reverse-i-search) " i wpisuję kilka znaków, takich jak Dev/C, które pojawiają się gdzieś w ścieżce, i pokazuje mi polecenie, które wydałem wtedy i mogę łatwo do niego wskoczyć ponownie.

To działa całkiem dobrze w praktyce. Ponieważ nie znajdzie wpisu, jeśli nie wpisałeś tej ścieżki od dłuższego czasu, co oznaczałoby, że praca nad ułatwieniem prawdopodobnie nie byłaby warto było. Ale na pewno go znajdzie, jeśli użyłeś go ostatnio. Tego właśnie potrzebuję.

W pewnym sensie jest to samoorganizująca się pamięć podręczna dla długich poleceń i nazw ścieżek:)

 3
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-22 04:31:35

Możesz rozważyć użycie skryptu takiego jak this w Twoim .bashrc. Używam go na co dzień, odkąd przeczytałem ten post. Cholernie przydatne.

 3
Author: wzzrd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:24:59

Użytkownik jhs zasugerował polecenia Pushd i Popd. Udostępniam tutaj Niektóre z moich skryptów Bash, które znalazłem w książce Unix Power Tools. Są bardzo fajne, gdy katalogi stają się zbyt długie:)

#Moving fast between directories 
alias pd=pushd 
alias pd2='pushd +2'  
alias pd3='pushd +3' 
alias pd4='pushd +4'

Polecenie 'pushd + n '"obraca" stos. Odwrotne polecenie 'popd + n' usuwa n wpisów stosu. Jeśli twój stos będzie zbyt długi, użyj 'repeat n popd'. W przypadku examle twój stos ma długość 12 katalogów:

repeat 11 popd 

Jeśli chcesz zobaczyć swój stos, napisz 'pushd'. Na dalsze lektura, polecam książkę na stronach 625-626.

 3
Author: Masi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-25 20:02:48

Istnieją fundamentalne, dobrze znane idee, takie jak tworzenie aliasów:

alias cdfoo="cd /long/path/to/foo"

A także "upuszczanie kamyczków"

export foo=/long/path/to/foo

A także uczynienie powyższego "projektowym". Używam katalogów "opartych na biletach".

 topdir=ticket_12345
 alias cdfoo="cd home/me/sandbox/$topdir/long/path/to/foo"
 export foo="/home/me/sandbox/$topdir/long/path/to/foo"

Ale poza tym wszystkim, czasami jest po prostu przydatne, aby przejść tam iz powrotem do miejsca, gdzie byłeś ostatnio, za pomocą menu wiersza poleceń. (pushd i popd są uciążliwe, IMHO).

Używam acd_func.sh (wymienione poniżej). Po zdefiniowaniu można wykonać

Cd --

To Zobacz listę ostatnich katalogów z menu numerycznym

Cd -2

Aby przejść do drugiego-najnowszego katalogu.

Bardzo łatwy w użyciu, bardzo poręczny.

Oto kod:

   # Insert into .profile, .bash_profile or wherever
    # acd_func 1.0.5, 10-nov-2004
    # petar marinov, http:/geocities.com/h2428, this is public domain

    cd_func ()

{
  local x2 the_new_dir adir index
  local -i cnt

  if [[ $1 ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=$1
  [[ -z $1 ]] && the_new_dir=$HOME

  if [[ ${the_new_dir:0:1} == '-' ]]; then
    #
    # Extract dir N from dirs
    index=${the_new_dir:1}
    [[ -z $index ]] && index=1
    adir=$(dirs +$index)
    [[ -z $adir ]] && return 1
    the_new_dir=$adir
  fi

  #
  # '~' has to be substituted by ${HOME}
  [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

  #
  # Now change to the new dir and add to the top of the stack
  pushd "${the_new_dir}" > /dev/null
  [[ $? -ne 0 ]] && return 1
  the_new_dir=$(pwd)

  #
  # Trim down everything beyond 11th entry
  popd -n +11 2>/dev/null 1>/dev/null

  #
  # Remove any other occurence of this dir, skipping the top of the stack
  for ((cnt=1; cnt <= 10; cnt++)); do
    x2=$(dirs +${cnt} 2>/dev/null)
    [[ $? -ne 0 ]] && return 0
    [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
    if [[ "${x2}" == "${the_new_dir}" ]]; then
      popd -n +$cnt 2>/dev/null 1>/dev/null
      cnt=cnt-1
    fi
  done

  return 0
}

alias cd=cd_func

if [[ $BASH_VERSION > "2.05a" ]]; then
  # ctrl+w shows the menu
  bind -x "\"\C-w\":cd_func -- ;"
fi
 2
Author: Leonard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-26 20:33:12

Może to być również przydatna funkcja do umieszczenia w .bashrc; przesuwa się ona w górę o kilka katalogów lub do katalogu nazwanego, tzn. jeśli jesteś w /a/b/c/d/, możesz zrobić up 3 lub up a, aby skończyć w a.

Nie mam pojęcia, gdzie to znalazłem; jeśli wiesz, skomentuj lub dodaj przypis.

function up()
{
    dir=""
    if [ -z "$1" ]; then
        dir=..
    elif [[ $1 =~ ^[0-9]+$ ]]; then
        x=0
        while [ $x -lt ${1:-1} ]; do
            dir=${dir}../
            x=$(($x+1))
        done
    else
        dir=${PWD%/$1/*}/$1
    fi
    cd "$dir";
}
 2
Author: Erik Hesselink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-28 18:44:32

Jeśli chcesz przełączyć się na zsh, jest to bardzo proste -- wystarczy użyć "alias-g" (Alias globalny, tzn. alias, który działa w dowolnym miejscu polecenia, a nie tylko w pierwszym słowie).

# alias -g c=/my/super/long/dir/name
# cd c
# pwd
/my/super/long/dir/name

W bash, myślę, że najbliższą rzeczą do stylu 'aliasing' jest napisanie funkcji:

function ccd {
  case "$1" in
    c) cd /blah/blah/blah/long/path/number/one ;;
    foo) cd /blah/blah/totally/different path ;;
    "multiword phrase") cd /tmp ;;
  esac
}

Oznacza to użycie czegoś innego niż" cd " jako polecenia, Gdy chcesz skrót, ale poza tym, to jest elastyczne; można również dodać "ls" do funkcji, tak, że zawsze przypomina, co jest w Katalog po płycie cd itp.

(zauważ, że aby użyć argumentu wielowordowego, jak powyżej, musisz zacytować go w wierszu poleceń, tak:

ccd "multiword phrase"
Więc to nie jest takie wygodne. Ale to zadziała, jeśli będzie trzeba.)
 2
Author: fholo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-30 15:15:38

Na podstawie sugestii Andrew Medico, sprawdź J

 2
Author: Dario,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-01 20:48:56

W Twoim .BASHRC find

PS1='${debian_chroot:+($debian_chroot)}[\033[01;32m]\u@\h[\033[00m]:[\033[01;34m]
 \W[\033[00m]\$ '
i zastąp \w na \w .Już to zmieniłem. To da Ci tylko główny katalog, w którym pracujesz. Możesz uzyskać pełny katalog wpisując pwd
 2
Author: Prabesh Subedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-29 14:04:47

Zajrzyj do pushd, który pozwala na utrzymanie stosu katalogów, które możesz przesuwać, odskakiwać lub zmieniać kolejność.

 1
Author: JasonSmith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-22 03:41:52
 1
Author: Andrew Medico,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-25 04:28:37

Zarządzanie wymaga zarówno szybkiego tworzenia jak i usuwania katalogów. Tworzenie wielu katalogów:

mkdir -p user/new_dir/new/_dir/.../new_dir

Usuń rekurencyjnie wiele katalogów (bądź bardzo ostrożny, gdy jesteś w niższych katalogach!):

rm -r dir/.../new_dir/

Do dalszej lektury Ściągawka może Ci pomóc:

Http://www.scribd.com/doc/2082838/Bash-Command-Line-History-Cheat-Sheet

Zawiera kilka bryłek, ale wydaje mi się, że raczej trudno je odczytać. Nie mogę dostać poleceń, takich jak Meta + >, pracuję. Prawdopodobnie pomogą Ci w nawigacji po długich katalogach.

 1
Author: Léo Léopold Hertz 준영,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-25 20:30:02

Zdaję sobie sprawę, że pytanie jest dość stare, ale żaden ze scenariuszy nie zadowolił mnie, więc napisałem nowy.

Oto wymagania, które miałem na myśli:

1) używaj tylko poleceń Basha - zamierzam używać tego na wielu różnych unicesach-Linuksie , cygwinie, HP-UX, AIX i kilku innych, więc nie mogłem polegać na tym, że grep jest spójny. Na szczęście mam Basha wszędzie, gdzie pracuję.

2) Krótki kod -- chciałem być w stanie powiązać to z kluczem na ekranie GNU i po prostu wcisnąć ten klucz aby wkleić skrypt do bieżącej powłoki bash, której używam, tak, że nie muszę konfigurować profili bash na każdym używanym systemie. Wszystko super długie byłoby irytujące i zajęło zbyt dużo czasu, aby wkleić.

3) Brak użycia plików -- nie chcę zaśmiecać współdzielonych loginów przypadkowymi plikami.

4) zachowuj się jak " cd " w normalnym przypadku. Nie chcę myśleć o tym, którego polecenia użyć, zanim zacznę pisać.

5) podaj "up" użycie jak ta odpowiedź: Jak zarządzać długo Ścieżki w Bash?

6) Zachowaj listę ostatnio używanych katalogów i przełącz się na najnowszy.

Oto scenariusz:

#Jump History - Isaiah Damron
function jfind() {
    lp=${JNHIST//==${PWD}==/==}
    lp=${lp%%${lp#==*$1*==}}
    lp=${lp##${lp%==*$1*==*}}
    lp=${lp//==/}
    [[ -d "$lp" ]] && echo $lp && return 0
    return 1;
}
function jadd() {
    [[ -z "$JNHIST" ]] && export JNHIST='=='
    [[ 3000 -lt ${#JNHIST} ]] && export JNHIST=${JNHIST:0:3000} && export JNHIST="${JNHIST%==*}=="
    export JNHIST="==$PWD${JNHIST//==${PWD}==/==}"
}
function j() {
    { cd $* 2> /dev/null && jadd; } \
    || { cd ${PWD/$1*/}$1 2> /dev/null && jadd; } \
    || { jfind $1 \
        && { cd $( jfind $1  ) 2> /dev/null && jadd; } ; } \
    || cd $*
}
function jh() {
    [[ -z "$1" ]] && echo -e ${JNHIST//==/\\n} 
    [[ -n "$1" ]] && jfind $1 && cd $(jfind $1) && jadd
}

Użycie:

jh [parameters]

Wywołane samodzielnie, bez żadnych parametrów, wyświetla listę bieżącej historii. Jeśli posiada parametr, to przeszukuje historię w poszukiwaniu ostatnio używanego katalogu zawierającego łańcuch $1 i płyt cd do niego.

j {parameters}

Robi cd parameters. Jeśli to się nie powiedzie, sprawdza, czy któryś z katalogów nadrzędnych $ PWD pasuje $1, a cd do niego. Jeśli to się nie powiedzie, to wywoła jh $1. Jeśli to się nie powiedzie, to wyświetli wynik cd parameters

Uwaga: użyłem '==' jako wewnętrznego separatora. Mam nadzieję, że nie masz żadnych katalogów zawierających'==', ale jeśli to zrobisz, będziesz musiał zmienić skrypt. Just: % s / = = / whatever / g

 1
Author: Xepo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:00:20