이전/다음 형제 디렉터리로 CD를 이동하는 방법은 무엇입니까?

이전/다음 형제 디렉터리로 CD를 이동하는 방법은 무엇입니까?

나는 종종 이런 프로젝트 디렉토리 레이아웃을 가지고 있습니다.

project
`-- component-a
|   `-- files...
`-- component-b
|   `-- files...
`-- component-c
    `-- files...

component저는 보통 디렉터리 중 하나에서 작업합니다. 디렉터리에 파일이 있기 때문입니다. 셸로 돌아갈 때 일반적으로 형제 디렉터리로 이동하면 됩니다. 특히 각 구성 요소에 스크립트할 수 없는 변경 사항을 적용해야 하는 경우에는 더욱 그렇습니다. 이런 경우에는 내가 작업하게 될 이전 형제나 다음 형제에 대해서도 관심이 없습니다.

명령을 정의 prev하거나 next단순히 cd이전 또는 다음 디렉터리로(알파벳순으로 또는 기타로) 이동할 수 있습니까? cd ../com<TAB><Arrow keys>항상 타이핑하는 것이 약간 구식이 되어가고 있기 때문입니다 .

답변1

Commandlinefu 솔루션을 사용하지 마십시오또 다른 대답: 안전하지 않고 비효율적입니다. 대신 bash. 이를 지속적으로 만들려면 내장 .bashrc되어 있고 간단하기 때문에 전역 순서를 사용하고 있습니다. 일반적으로 글로벌 주문그러나 대부분의 로케일에서는 알파벳순으로 정렬됩니다. 이동할 다음 또는 이전 디렉터리가 없으면 오류 메시지가 표시됩니다. 특히 루트 디렉터리에서 next또는 을 시도하면 오류가 표시됩니다 .prev/

## bash and zsh only!
# functions to cd to the next or previous sibling directory, in glob order

prev () {
    # default to current directory if no previous
    local prevdir="./"
    local cwd=${PWD##*/}
    if [[ -z $cwd ]]; then
        # $PWD must be /
        echo 'No previous directory.' >&2
        return 1
    fi
    for x in ../*/; do
        if [[ ${x#../} == ${cwd}/ ]]; then
            # found cwd
            if [[ $prevdir == ./ ]]; then
                echo 'No previous directory.' >&2
                return 1
            fi
            cd "$prevdir"
            return
        fi
        if [[ -d $x ]]; then
            prevdir=$x
        fi
    done
    # Should never get here.
    echo 'Directory not changed.' >&2
    return 1
}

next () {
    local foundcwd=
    local cwd=${PWD##*/}
    if [[ -z $cwd ]]; then
        # $PWD must be /
        echo 'No next directory.' >&2
        return 1
    fi
    for x in ../*/; do
        if [[ -n $foundcwd ]]; then
            if [[ -d $x ]]; then
                cd "$x"
                return
            fi
        elif [[ ${x#../} == ${cwd}/ ]]; then
            foundcwd=1
        fi
    done
    echo 'No next directory.' >&2
    return 1
}

¹ 가능한 모든 디렉터리 이름을 처리하지는 않습니다. 출력을 구문 분석하는 것은 ls결코 안전하지 않습니다..

² cd매우 효율적일 필요는 없지만 6개 프로세스는 다소 과도합니다.

답변2

다음 기능을 사용하면 형제 디렉터리를 변경할 수 있습니다(bash 기능).

function sib() {
    ## sib  search sibling directories 
    ##   prompt for choice (when two or more directories are found, current dir is removed from choices) 
    ##   change to directory after selection 
    local substr=$1
    local curdir=$(pwd)
    local choices=$(find .. -maxdepth 1 -type d -name "*${substr}*" | grep -vE '^..$' | sed -e 's:../::' | grep -vE "^${curdir##*/}$" | sort)
    if [ -z "$choices" ]; then
        echo "Sibling directory not found!"
        return
    fi
    local count=$(echo "$choices" | wc -l)
    if [[ $count -eq 1 ]]; then
        cd ../$choices
        return 
    fi
    select dir in $choices; do
        if [ -n "$dir" ]; then
            cd ../$dir
        fi
        break
    done
}

사용 예:

$ tree
  .
  ├── component-aaa-01
  ├── component-aaa-02
  ├── component-bbb-01
  ├── component-bbb-02
  ├── component-ccc-01
  ├── component-ccc-02
  └── component-ccc-03
  7 directories, 0 files
  $ cd component-aaa-01/
  $ sib bbb-01
  $ pwd
  component-bbb-01
  $ sib bbb
  $ pwd
  component-bbb-02
  $ sib ccc
  1) component-ccc-01
  2) component-ccc-02
  3) component-ccc-03
  #? 3
  $ pwd
  component-ccc-03
  $ sib 01
  1) component-aaa-01
  2) component-bbb-01
  3) component-ccc-01
  #? 2
  $ pwd
  component-bbb-01

답변3

팁을 찾았어요명령줄 fu.com. 찾기 쉽도록 여기에 다시 게시하고, next사용하면서 설명과 명령을 추가합니다.

alias prev='cd ../"$(ls -F .. | grep '/' | grep -B1 -xF "${PWD##*/}/" | head -n 1)"'
alias next='cd ../"$(ls -F .. | grep '/' | grep -A1 -xF "${PWD##*/}/" | tail -n 1)"'

마법은 "$(...)" 블록에 있습니다. 다음과 같이 파이프를 통해 서로에게 몇 가지 명령을 전달합니다.

ls -F .. |   # list items in parent dir; `-F` requests filetype indicators
grep '/' |   # select the directories (written as  `mydir/`)
grep -B1 -xF "${PWD##*/}/" |   # search for the name of the current directory in the output;
                               # print it and the line preceding it
head -n 1    # the first of those two lines contains the name of the previous sibling

관련 정보