Как управлять длинными путями в Bash?

у меня проблема с управлением длинными путями. Как я могу быстро добраться до таких путей, как

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

я попробовал псевдоним

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

но я не могу сделать псевдонимы для двух отдельных слов. У меня есть длинные списки псевдонимов Bash и путей в CDPATH, поэтому я не решаюсь сделать их больше. Как управлять длинными путями?

[идеи для ответов]

ответ пользователя litb показал некоторые из моих проблем в управлении. Такие вещи, как "CTRL+R","!-3:1:2:4:x" и "последовательный поиск", сложно для меня. Они, вероятно, помогают в навигации по длинным каталогам и, в некотором смысле, в управлении.

17 ответов


рассмотрите возможность использования символических ссылок. У меня есть где я размещаю ссылки на все мои текущие проекты.

вы также можете использовать переменные оболочки:

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

затем:

cd "$c"

используя ссылки вероятно, лучшая идея; но вы можете сделать это еще проще, чем сбрасывать их все в свой домашний каталог.

Как вы упомянули, BASH имеет функцию под названием переменную окружения cdpath что очень удобно здесь.

просто сделайте скрытую папку в своем homedir (чтобы она не слишком загромождала ваш homedir):

$ 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

это создает каталог в вашем homedir под названием ".пути", который содержит символические ссылки на все ваши длинные местоположения каталогов, которые вы регулярно используете, затем устанавливает переменную CDPATH bash в этот каталог (в вашем .bashrc )и перечитывает.файл bashrc.

теперь вы можете перейти к любому из этих путей из в любом месте:

$ cd project
$ cd backups

оставляя вас с коротким CDPATH, не загромождая алиасы, и что более важно: действительно простой способ перейти к этим длинным путям от другие приложения, например, UI-приложения, просто перейдя в~/.пути или добавление этого каталог на боковой панели приложения пользовательского интерфейса или около того.

вероятно, самое простое всестороннее решение, которое вы можете иметь.


создать симлинки в вашем домашнем каталоге (или где-то еще по вашему выбору)

ln -s longDirectoryPath ~ / MySymLinkName

посмотреть man ln для более подробной информации.


наверное самое простое решение-использовать:

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

если вы действительно работаете только над одним проектом за раз. Если вы работаете над несколькими проектами, у вас может быть другой псевдоним, который изменил каталоги в этих псевдонимах выше.

Итак, вы бы использовали что-то вроде:

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

поскольку это полезная вещь, я решил собрать серию скриптов, которые можно использовать. Все они основаны на файле конфигурации, который вы размещаете в вашем домашнем каталоге вместе с псевдонимами исходных сценариев. Файл "~/.cdx_data" имеет вид:

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

и перечисляет все соответствующие проекты (scrabble и sodoku в этом случае) и их каталоги (которые могут отличаться для каждого проекта, но имеют top, bin, src и данные в этом примере).

первое действие-инициализировать материал, поэтому поставьте:

. ~/.cdx_init

в конце .bash_profile и создать as:

alias cdxl='. ~/.cdx_list'
alias projl='. ~/.cdx_projlist'
alias cdx='. ~/.cdx_goto'
alias proj='. ~/.cdx_proj'

это устанавливает четыре псевдонима для источника файлов, которые я включу ниже. Использование:

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).

фактический сценарий следовать. Во-первых, ".cdx_list" который просто перечисляет разрешенные каталоги в текущем проекте (конвейеры разбиты на несколько строк для удобства чтения, но все они должны быть в одной строке).

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

аналогично, ".cdx_projlist" показывает все возможные проекты:

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

в мясистых сценариях,".cdx_proj" наборы и/или показывает текущий проект:

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

и ".cdx_goto" то же самое для каталогов в рамках проекта:

if [[ "" == "." ]] ; then
    CDX_TMP="${CDX_DIR}"
else
    CDX_TMP=""
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

он использует три переменные среды, которые зарезервированы для собственного использования:"CDX_PROJ", "CDX_DIR" и "CDX_TMP". Кроме этих и вышеупомянутых файлов и псевдонимов, другие ресурсы не используются. Это самое простое, но самое адаптируемое решение, которое я мог придумать. Удачи.


пересмотр. Сегодня я получил эту ссылку с сайта социальных закладок, тогда я сразу вспомнил этот вопрос:

навигация с bm

мы сохраняем простые текстовые закладки файл и использовать инструмент под названием bm поисковые запросы. Инструмент также может быть используется для редактирования индекса закладки динамически, как показано ниже, где мы добавить каталоги из предыдущего пример к индексу.


Как только я cd'ed в такой длинный каталог, у меня есть это в истории. Тогда я просто набираю Ctrl-R для подсказки "(обратный поиск) " и введите несколько символов, например Dev/C которые появляются где-то на пути, и он показывает мне команду, которую я выдал тогда, и я могу легко перейти к ней снова.

это работает довольно хорошо на практике. Потому что он не найдет запись, если вы не набрали этот путь в течение некоторого времени, что означало бы выполнение работы, чтобы сделать вещи проще наверное, не стоит тратить время. Но он определенно найдет его, если вы использовали его недавно. Именно это мне и нужно.

в некотором роде это самоорганизующийся кэш для длинных команд и имен путей:)


возможно, вы захотите использовать такой скрипт, как этой в вашей .bashrc следующее. Я использовал его ежедневно с тех пор, как прочитал этот пост. Чертовски полезно.


в jhs, выполните следующие команды пользователя предложили команды pushd и popd-команды. Я делюсь здесь некоторыми из моих bash-скриптов, которые я нашел в Unix Power Tools-book. Они очень крутые, когда ваши каталоги становятся слишком длинными :)

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

команда 'pushd +n '"вращает" стек. Обратная команда 'popd +n' удаляет запись N стека. Если ваш стек становится слишком длинным, используйте повторять командой popd'. Например, ваш стек составляет 12 каталогов:

repeat 11 popd 

когда вы хотите увидеть свой стек, напишите 'команда pushd'. Для дальнейшего чтения рекомендую книгу на страницах 625-626.


есть фундаментальные известные идеи, такие как создание псевдонимов:

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

а также "падение гальки"

export foo=/long/path/to/foo

и выше "на основе проекта". Я использую 'билет' каталоги.

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

но помимо всего этого, иногда просто удобно прыгать туда и обратно, где вы были в последнее время, используя меню командной строки. (pushd и popd громоздки, ИМХО).

Я использую acd_func.sh (перечислены ниже). После определения, вы можете do

компакт-диск --

чтобы просмотреть список последних каталогов, с числовым меню

cd -2

чтобы перейти ко второму самому последнему каталогу.

очень прост в использовании, очень удобно.

вот код:

   # 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 [[  ==  "--" ]]; then
    dirs -v
    return 0
  fi

  the_new_dir=
  [[ -z  ]] && 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

это также может быть полезной функцией для ввода вашего .bashrc; он перемещается либо в несколько каталогов, либо в именованный каталог, т. е. если вы находитесь в /a/b/c/d/ можно сделать up 3 или up a в итоге a.

Я понятия не имею, где я это нашел; если вы знаете, пожалуйста, прокомментируйте или добавьте атрибуцию.

function up()
{
    dir=""
    if [ -z "" ]; then
        dir=..
    elif [[  =~ ^[0-9]+$ ]]; then
        x=0
        while [ $x -lt ${1:-1} ]; do
            dir=${dir}../
            x=$(($x+1))
        done
    else
        dir=${PWD%//*}/
    fi
    cd "$dir";
}

Если вы хотите переключиться на zsh, это очень просто-просто используйте "alias-g" (глобальный псевдоним, т. е. псевдоним, который работает в любом месте команды, а не только первое слово).

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

в bash, я думаю, что ближе всего к стилю "сглаживания" вы получите, чтобы написать функцию:

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

Это означает использование чего-то другого, кроме "cd" в качестве команды, когда вам нужен ярлык, но кроме этого, он гибкий; вы также можете добавить" ls " в функцию, чтобы она всегда напоминает вам, что в каталог после CD и т. д.

(обратите внимание, что для использования многословного аргумента, как указано выше, вам нужно процитировать его в командной строке, например:

ccd "multiword phrase"

Так что это не очень удобно. Но это сработает, если понадобится.)


основываясь на предложении Эндрю медико, проверьте J


в вашей .bashrc и найти

PS1='${debian_chroot:+($debian_chroot)}[3[01;32m]\u@\h[3[00m]:[3[01;34m]
 \W[3[00m]$ '
и замените \w С \W.Я уже изменил его здесь. Это даст вам только основной каталог, в котором вы работаете. Вы можете получить полный каталог, введя pwd

посмотреть в pushd, что позволяет вам поддерживать стек каталогов, на которые вы можете нажать, выскочить или переставить.


проверить autojmp или dirmarks


управление требует быстрого создания и удаления каталогов. Создайте много directiories:

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

удалить рекурсивно много каталогов (будьте очень осторожны, когда вы находитесь в более низких каталогах!):

rm -r dir/.../new_dir/

для дальнейшего чтения, шпаргалка может помочь вам:

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

Он содержит некоторые самородки, но я нахожу это довольно трудно читать. Я не могу получить команды, такие как Meta+>, работающие. Они, вероятно, помогут вам в навигации по длинным каталогам.


Я понимаю, что вопрос довольно старый, но ни один из сценариев меня не удовлетворил, поэтому я написал новый.

вот требования, которые я имел в виду:

1) Используйте только команды bash - я намерен использовать это на многих разных unices-Linux, cygwin, HP-UX, AIX и несколько других, поэтому я не мог зависеть от согласованности grep. К счастью, у меня есть bash везде, где я работаю.

2) короткий код -- я хотел иметь возможность привязать это к ключу на экране GNU, и просто нажмите эту клавишу, чтобы вставить скрипт в текущую оболочку bash, которую я использую, так что мне не нужно настраивать профили bash в каждой системе, которую я использую. Все, что супер долго будет раздражать и займет слишком много времени, чтобы вставить.

3) нет использования файлов - не хочу быть засорение общих входов со случайными файлами.

4) действуйте так же, как" cd " в обычном случае. Не хочу думать о том, какую команду использовать, прежде чем я начну печатать.

5) обеспечьте" вверх " использование как ответ: как управлять длинными путями в Bash?

6) сохраните список недавно использованных каталогов и переключитесь на самые последние.

вот скрипт:

#Jump History - Isaiah Damron
function jfind() {
    lp=${JNHIST//==${PWD}==/==}
    lp=${lp%%${lp#==**==}}
    lp=${lp##${lp%==**==*}}
    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/*/} 2> /dev/null && jadd; } \
    || { jfind  \
        && { cd $( jfind   ) 2> /dev/null && jadd; } ; } \
    || cd $*
}
function jh() {
    [[ -z "" ]] && echo -e ${JNHIST//==/\n} 
    [[ -n "" ]] && jfind  && cd $(jfind ) && jadd
}

использование:

jh [parameters]

если вызывается самостоятельно, без каких-либо параметров, он выводит список текущей истории. Если у него есть параметр, то он ищет в истории самый последний используемый каталог, содержащий строку $1, и cd для он.

j {parameters}

тут cd parameters. Если это не удается, он проверяет, соответствует ли какой-либо из родительских каталогов $PWD $1 и cd к нему. Если это не удается, то он называет jh . Если это не удается, то он выводит результат cd parameters

Примечание: я использовал '==' в качестве внутреннего разделителя. Надеюсь, у вас нет каталогов, содержащих'==', но если вы это сделаете, вам придется изменить сценарий. Просто: %s/==/whatever / g