특정 폴더에 올 때까지 CD를


16

나는 마 젠토에서 많은 일을하고, 함께 일하는 많은 사람들도 일을하며, 타이핑을하는 것은 귀찮아진다 :

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

루트 'httpdocs'폴더에서 여전히 몇 개의 디렉토리를 찾기 위해이 의사 코드를 따르는 스크립트를 만들려고합니다.

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

꽤 단순 해 보입니다. 현재 작업 디렉토리의 마지막 부분이 httpdocs인지 확인하기 위해 일종의 grep을 수행해야한다고 가정하고 있습니다.

나는 이것에 대해 bash를 배우고 있었지만 이미 비슷한 것이있을 것 같지만 구문은 나를 끝내지 못한다.

답변:


8

스크립트는 새 쉘에서 실행되므로 원래 쉘의 디렉토리를 변경할 수 없으므로 스크립트가 아닌 쉘 함수 여야합니다 .

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

물론 원하는대로 함수의 이름을 지정할 수 있습니다.

몇 가지 설명 : 첫 번째 테스트 ( $PWD != '/')는 cdroothttpdocs 폴더 안에 있지 않은 경우를 대비 한 안전 장치입니다 . 루트에 도착하면 멈출 것입니다.

두 번째 테스트 ( ${PWD##*/} != 'httpdocs')는 조금 더 복잡합니다. $PWD현재 디렉토리의 경로를 포함하는 변수입니다. ${PWD##*/}마지막 슬래시를 포함하여 모든 것을 잘라냅니다.


이 반복적 인 단점은 cd -나중에 나중에 원래 위치로 돌아갈 수있는 능력을 상실한다는 것 입니다.
Ezequiel Muns

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

@Cesar는 globstar ( **)를 사용합니다 . bash 쉘에서이 기능을 사용하려면을 사용하십시오 shopt -s globstar.
dogbane

2
이것은 훌륭하게 이루어졌습니다. 저는 두 번 공표 할 수 있기를 바랍니다.
droope

1
jd기능 에 동적 쇼핑 감지 및 활성화 기능 이 포함되어 있습니다 ( gist.github.com/Rob--W/5888648 참조) . 나는 Bash 4.2.45에서만 테스트 했으므로 YMMV.
Rob W

5

.bashrc내가 생각할 수있는 가장 간단한 bash 함수는 다음 과 같습니다 (루프 또는 외부 프로세스를 사용하지 않기 때문에 간단합니다).

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

이는 사용 패턴 대체 한 후 모든 것을 대체 할 매개 변수 확장을 /httpdocs/$PWD`/ httpdocs '로. bash 확장 구문에서 슬래시와 구분하기 위해 경로에서 슬래시를 이스케이프해야하기 때문에 매우 혼란스럽게 보입니다. 또한 교체 문자열에서 슬래시를 이스케이프 처리하지 않으므로 일관성이 없어 보입니다.

더있는 경우 /httpdocs/현재 경로에 다음에는 대체가 수행되지 않으며 단지 현재 디렉토리로 변경됩니다.

예를 들어, 대체 대체 할 /a/b/c/httpdocs/e/f/g/a/b/c/httpdocs하고 cd그 디렉토리에.

하위 프로세스는 상위 프로세스의 상위 디렉토리를 변경할 수 없으므로 함수는 현재 쉘 환경 (함수 또는 별명)에 있어야합니다. 이것이 내가 .bashrc쉘 스크립트가 아닌 귀하의 스크립트에 넣는 이유 입니다.


덧붙여서, 이것이 가능한 한 계층 구조에서 최대한 높아질 것이라고 언급 할 가치가 있습니다 (어쨌든 가장 유용한 사용 사례 일 것입니다).
Ibrahim

3

프로필에 다음과 같은 것을 넣을 수도 있습니다.

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

입력 만하면 현재 경로 cdh의 최상위 httpdocs디렉토리로 이동합니다.


2

문제를 완전히 해결하지는 못하지만 cd ../../../../../../약간의 비용을 절약 할 수 있습니다. 나는에서이 문제를 차용 한 사용자 불명 의 포스트 여기 .


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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.