Зберігайте компакт-диск до тих пір, поки в певній папці


16

Я багато працюю в Magento, і так багато людей, з якими я працюю, і це стає прикро, щоб набрати:

cd ../../../../../../

Щоб знайти лише кілька каталогів із вашої кореневої папки "httpdocs", тому я намагаюся створити сценарій, який відповідає цьому псевдо-коду:

while lowest level directory != httpdocs
    cd ../
end while;

Здається, це досить просто, я припускаю, що мені доведеться виконати певну форму грепінгу, щоб перевірити, чи є остання частина поточного робочого каталогу httpdocs, якщо не просто продовжувати підніматися на рівень, поки це не відповідає дійсності.

Я дивився на вивчення баш для цього, хоча здається, що там має бути щось таке, що схоже, і синтаксис спантеличує мене без кінця.

Відповіді:


8

Це має бути функцією оболонки , а не сценарієм, оскільки сценарій виконується в новій оболонці (і, отже, не може змінити каталог вихідної оболонки).

function cdroot()
{
  while [[ $PWD != '/' && ${PWD##*/} != 'httpdocs' ]]; do cd ..; done
}

Ви, звичайно, можете назвати функцію, що завгодно.

Деякі пояснення: Перший тест ( $PWD != '/') - це незахищений випадок, cdrootякщо ви не знаходитесь у папці httpdocs. Він зупиниться, коли ви дістанетесь до кореня.

Другий тест ( ${PWD##*/} != 'httpdocs') трохи складніше. $PWD- змінна, що містить шлях поточного каталогу. ${PWD##*/}обрізає все, включаючи останню косу рису.


Мінус цього ітеративного полягає в тому, що ви втрачаєте здатність просто робити cd -згодом, щоб повернутися туди, де ви були.
Езеквіль Мунс

27

У мене є функція, що називається uptoв моєму .bashrc, що дозволяє вам перейти до будь-якого каталогу поточного шляху за назвою:

upto ()
{
    if [ -z "$1" ]; then
        return
    fi
    local upto=$1
    cd "${PWD/\/$upto\/*//$upto}"
}

У мене також є завершення цієї функції, так що вона дає мені дійсні імена каталогів та завершення, коли я натискаю вкладку:

_upto()
{
    local cur=${COMP_WORDS[COMP_CWORD]}
    local d=${PWD//\//\ }
    COMPREPLY=( $( compgen -W "$d" -- "$cur" ) )
}
complete -F _upto upto

Крім того, у мене є ще одна функція, jdяка дозволяє мені переходити до будь-якого каталогу нижче поточного:

jd(){
    if [ -z "$1" ]; then
        echo "Usage: jd [directory]";
        return 1
    else
        cd **"/$1"
    fi
}

Приклад:

[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto h[TAB][TAB]
habitat       hippopotamus
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ upto hippopotamus
[/www/public_html/animals/hippopotamus] $ jd images
[/www/public_html/animals/hippopotamus/habitat/swamps/images] $ 

Ви також можете додати псевдонім для upto httpdocs.
cjm

@drogbane: Схоже jd, не в кожному випадку ви хочете пояснити, як це працює?
Сезар

@Cesar він використовує globstar ( **). Щоб увімкнути цю функцію у використанні оболонки bash shopt -s globstar.
собачка

2
Це так блискуче зроблено, я хотів би, щоб я міг проголосувати двічі.
droope

1
Я включив у функцію динамічне виявлення і активацію зйомкиjd , див. Gist.github.com/Rob--W/5888648 . Я протестував його лише з Bash 4.2.45, так що YMMV.
Роб Ш

5

Найпростіша функція bash, яку ви можете вкласти у свою, .bashrcяку я можу придумати (проста, оскільки вона не використовує циклів або зовнішніх процесів), це:

cdup() {
    cd "${PWD/\/httpdocs\/*//httpdocs}"
}

Це використовує розширення параметра заміни Шаблону, щоб замінити все після /httpdocs/в $PWDна `/ httpdocs '. Це виглядає дуже безладним, оскільки нам потрібно уникнути передніх косої риски в шляху, щоб відрізнити їх від передніх косої частини в синтаксисі розгортання bash. Плюс не уникайте косої риски в рядку заміни, тому це також виглядає непослідовно.

Якщо немає /httpdocs/в поточному шляху, то заміни не буде виконуватися, і він просто зміниться на поточний каталог.

Наприклад, заміна буде замінити /a/b/c/httpdocs/e/f/gз /a/b/c/httpdocsі cdв цей каталог.

Функція повинна знаходитись у вашому поточному середовищі оболонки (як функція чи псевдонім), оскільки дочірній процес не може змінити поточний каталог свого батьківського. Ось чому я кажу, щоб це було у вашому .bashrcсценарії, а не в оболонці.


До речі, варто згадати, що це підніме вас якомога вище в ієрархії (що, мабуть, найкорисніший випадок використання у будь-якому разі).
Ібрагім

3

Ви також можете розмістити щось подібне у своєму профілі:

alias cdh='cd $(echo $PWD | sed -e "s/\(.*\/httpdocs\)\/.*/\1/")'

Щойно ввівши cdh, ви перейдете до найвищого httpdocsкаталогу у вашому поточному шляху.


2

Це не повністю вирішує вашу проблему, але це дозволить заощадити на роботі cd ../../../../../../. Я запозичив це від користувача невідомого «s пост тут .


вгору N

стрибнути N каталогів вгору в дерево каталогів

Замість набору тексту

cd ../../../..

ви просто набираєте текст

up 4

і а

cd -    

поверне тебе назад

Покладіть функцію у свій .bashrc, щоб використовувати її.

# (c) 2007 stefan w. GPLv3          
function up {
ups=""
for i in $(seq 1 $1)
do
        ups=$ups"../"
done
cd $ups
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.