디렉터리에서 파일을 찾고 있으므로 find 명령을 사용하면 파일이 있는 디렉터리 경로가 표시됩니다.
전임자.
$find . -name file.txt
/folder/path/file-contents/file.txt
이제 디렉토리에 경로를 복사한 다음 cd 명령을 사용하여 디렉토리를 붙여넣는 것보다 더 빠르게 디렉토리에 들어갈 수 있는 방법이 있는지 궁금합니다.
또한 find 명령을 사용한 후 두 개의 경로가 나열되면 해당 경로를 복사하여 붙여넣지 않고 주어진 두 번째 경로로 cd할 수 있는 방법이 있습니까?
터미널 작업 속도를 높이는 데 도움이 될지 궁금합니다.
답변1
( bash
추가 하향 변경)
셸에서는 패턴 끝에 globbing 한정자를 추가하여 zsh
globbing 패턴의 마지막 일치 항목을 얻을 수 있습니다. ([-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
설정 globstar
과 dotglob
셸 옵션을 먼저 사용한다는 가정 하에 shopt -s globstar dotglob
다음과 같은 작업을 두 단계로 수행할 수 있습니다 .
$ set -- ./**/*.sh
$ cd "$( dirname -- "${@: -1}" )"
이는 위치 인수를 일치하는 경로 이름 목록으로 설정한 다음 호출의 마지막 인수를 사용 dirname
하고 그 결과를 와 함께 사용합니다 cd
. 그러나 를 사용하는 경우 bash
glob의 확장자가 일반 파일이라는 보장은 없습니다.
대신 명명된 배열을 사용할 수 있습니다.
$ 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.txt
zsh
(:h)
Ctrl+W/
select-word-style
경로에 공백이나 제어 문자 또는 분해된 형태의 문자가 포함되어 있으면 이 방법이 작동하지 않습니다.
쉘 특정 문자(예 '
: , "
, ;
, &
...)가 포함된 경우 해당 문자를 인용해야 합니다( 에서는 위젯을 zsh
사용할 수 있습니다 ( 기본적으로 이 작업을 수행하도록 바인딩됨)).quote-region
Alt+"
답변4
당신은 시도 할 수 있습니다 cdi
(https://github.com/antonioolf/cdi)
이 명령줄 도구는 디렉터리 검색 환경을 개선하기 위해 만들어졌습니다(교체 cd
).
기본적으로 대화형 명령줄 디렉터리 브라우저입니다.
여러분이 해야 할 일은 cdi
명령을 실행하고 화살표 키를 사용하여 폴더를 탐색한 다음( Right폴더를 입력 하고 Left뒤로 가서 목록을 스크롤하는 것) 원하는 디렉터리를 찾았을 때 누르기만 하면 실제 명령을 실행하는 것뿐입니다.UpDownEntercd
저장소 보기