이전 명령에 디렉토리를 나열한 후 디렉토리에 들어가는 더 빠른 방법은 무엇입니까?

이전 명령에 디렉토리를 나열한 후 디렉토리에 들어가는 더 빠른 방법은 무엇입니까?

디렉터리에서 파일을 찾고 있으므로 find 명령을 사용하면 파일이 있는 디렉터리 경로가 표시됩니다.

전임자.

$find . -name file.txt
/folder/path/file-contents/file.txt

이제 디렉토리에 경로를 복사한 다음 cd 명령을 사용하여 디렉토리를 붙여넣는 것보다 더 빠르게 디렉토리에 들어갈 수 있는 방법이 있는지 궁금합니다.

또한 find 명령을 사용한 후 두 개의 경로가 나열되면 해당 경로를 복사하여 붙여넣지 않고 주어진 두 번째 경로로 cd할 수 있는 방법이 있습니까?

터미널 작업 속도를 높이는 데 도움이 될지 궁금합니다.

답변1

( bash추가 하향 변경)

셸에서는 패턴 끝에 globbing 한정자를 추가하여 zshglobbing 패턴의 마지막 일치 항목을 얻을 수 있습니다. ([-1])이 예에서는 이름이 다음으로 끝나는 파일을 찾습니다 .sh.

$ print -rC1 ./**/*.sh
./local/sbin/scheduled-backup.sh
./local/sbin/update-cvs.sh
./local/sbin/update-system.sh
./local/sbin/zerofill.sh
$ print -rC1 ./**/*.sh(.D[-1])
./local/sbin/zerofill.sh

.한정자에 및 를 추가하면 D일반 파일만 찾고 숨겨진 이름( dotglob에 설정된 대로 bash)도 일치하게 됩니다.

발견된 파일이 포함된 디렉터리로 변경하는 데 사용할 수 있습니다.

$ cd ./**/*.sh(.D[-1]:h)

(여기서는 csh/vi 스타일 :h수정자를 사용하여머리파일의 (디렉토리 이름))

(패턴이 아닌) 파일 이름을 취하는 쉘 함수로서:

goto_file () cd ./**/$1(.D[-1]:h)

이것은 파일 이름이 괜찮은지(개행 등을 포함하지 않음)에 의존하지 않습니다.


에서는 bash설정 globstardotglob셸 옵션을 먼저 사용한다는 가정 하에 shopt -s globstar dotglob다음과 같은 작업을 두 단계로 수행할 수 있습니다 .

$ set -- ./**/*.sh
$ cd "$( dirname -- "${@: -1}" )"

이는 위치 인수를 일치하는 경로 이름 목록으로 설정한 다음 호출의 마지막 인수를 사용 dirname하고 그 결과를 와 함께 사용합니다 cd. 그러나 를 사용하는 경우 bashglob의 확장자가 일반 파일이라는 보장은 없습니다.

대신 명명된 배열을 사용할 수 있습니다.

$ stuff=( ./**/*.sh )
$ cd "$( dirname -- "${stuff[-1]}" )"

쉘 함수로서 파일 이름(패턴 아님)을 가져옵니다.

goto_file () {
    local pathnames

    pathnames=( ./**/"$1" )
    cd "$( dirname -- "${pathnames[-1]}" )"
}

이를 위해서는 적어도 globstar이 옵션이 호출 셸에 설정되어 있어야 합니다. 하지만 필요에 따라 설정할 수 있습니다.

goto_file () {
    local pathnames

    if [[ $BASHOPTS != *globstar* ]]; then
        shopt -s globstar
        trap 'shopt -u globstar' RETURN   # unset globstar on return
    fi

    pathnames=( ./**/"$1" )
    cd "$( dirname -- "${pathnames[-1]}" )"
}

변형과 마찬가지로 이는 zsh파일 이름이 일반(개행 문자 등을 포함하지 않음)인 것에 의존하지 않지만 디렉터리 이름은 개행 문자로 끝날 수 없습니다. dirname이러한 문자는 명령 대체가 해당 값을 반환할 때 제거되기 때문입니다.

답변2

이를 사용하여 검색 중인 파일이 들어 있는 디렉토리의 이름을 얻을 수 있으며 마지막 항목을 얻는 데 dirname사용할 수 있습니다 . tail -1기술적으로 head -2 | tail -1두 개 이상이면 이를 사용하여 두 번째 목록을 얻을 수 있습니다. 목록이 1개만 있으면 1을 반환합니다.

좋다:

cd $(dirname $(find . -name file.txt | tail -1))

또는:

cd $(dirname $(find . -name file.txt | head -2 | tail -1))

이것이 실제로 더 빠른지는 잘 모르겠지만 마우스로 텍스트를 선택하고 복사하는 번거로움을 덜어줍니다.

이것을 쉘 rc의 함수로 작성할 수 있습니다(예: ) .bashrc.

function goto-file() {
    file=$1
    cd $(dirname $(find . -name $file | tail -1))
}

그러면 CLI 효율성은 다음을 입력하는 것만큼 간단해집니다 goto-file file.txt.

어쩌면 더 나은 접근 방식은 검색하려는 경로를 통과하도록 허용하는 것입니까? 이것은 방금 내 함수에 추가한 함수입니다 .bashrc.

function goto-file() {
    if [ $# -gt 2 -o $# -lt 1 ]; then
        echo "Usage: goto-file [path] filename"
    else
        if [ $# -eq 2 ]; then
            path=$1
            file=$2
        elif [ $# -eq 1 ]; then
            path='.'
            file=$1
        fi

        cd $(dirname $(find $path -name $file | tail -1))
    fi
}

매우 편리합니다. 감사해요.

답변3

xterm터미널 에뮬레이터를 사용하는 경우 바인딩할 수 있습니다.dabbrev-expand() 행동( emacs'를 흉내내다동적 약어기능)을 키에 연결합니다.

예를 들어, 리소스 파일을 넣습니다(X 서버의 모든 클라이언트가 영향을 받도록 X 서버에 로드하거나 xrdb, 연결된 X 서버에 관계없이 모든 xterm 호출이 컴퓨터에서 이루어지도록 파일 xterm에 넣습니다). XENVIRONMENT) 영향을 받음) 예를 들면 다음과 같습니다.

XTerm.VT100.translations:             #override\
        Meta <KeyPress> /: dabbrev-expand()

Alt+/그런 다음 , 를 사용하여 xterm화면에 표시된 내용을 기반으로 완성을 제공합니다(커서에 가장 가까운 것부터 시작).

따라서 표시한 후 find ...for를 입력하여 확장한 다음 후행 부분을 제거하면 /folder/path/file-contents/file.txt됩니다 (또는 use와 같이 단어 구분 기호로 처리하도록 구성된 경우 사용, 추가 또는 사용).cd /Alt+/xterm//folder/path/file-contents/file.txtzsh(:h)Ctrl+W/select-word-style

경로에 공백이나 제어 문자 또는 분해된 형태의 문자가 포함되어 있으면 이 방법이 작동하지 않습니다.

쉘 특정 문자(예 ': , ", ;, &...)가 포함된 경우 해당 문자를 인용해야 합니다( 에서는 위젯을 zsh사용할 수 있습니다 ( 기본적으로 이 작업을 수행하도록 바인딩됨)).quote-regionAlt+"

답변4

당신은 시도 할 수 있습니다 cdi(https://github.com/antonioolf/cdi)

이 명령줄 도구는 디렉터리 검색 환경을 개선하기 위해 만들어졌습니다(교체 cd).

기본적으로 대화형 명령줄 디렉터리 브라우저입니다.

여러분이 해야 할 일은 cdi명령을 실행하고 화살표 키를 사용하여 폴더를 탐색한 다음( Right폴더를 입력 하고 Left뒤로 가서 목록을 스크롤하는 것) 원하는 디렉터리를 찾았을 때 누르기만 하면 실제 명령을 실행하는 것뿐입니다.UpDownEntercd

저장소 보기

관련 정보