"/" 발생 횟수를 기준으로 결과를 정렬 $ find . -name scripts -type d
한 다음 첫 번째 결과를 선택하는 가장 좋은 방법은 무엇입니까?
cd
내 프로젝트의 공용 폴더를 가리키는 함수를 만들고 싶습니다 . 나는 그것이 당신의 상대 디렉토리에 기초하여 유연해지기를 원합니다.
따라서 폴더 구조가 모두 비슷한 10개의 프로젝트가 있는 경우:
~/project-a/project/folder/structure
~/project-b/project/folder/structure
~/project-c/project/folder/structure
저 할 수 있어요:
$ cd ~/project-a
$ cdd structure
~/project-a/project/folder/struct에 배치됩니다.
고쳐 쓰다
예를 들어 다음과 같이 예측 가능한 방식으로 결과를 정렬할 수 없습니다.
$ find . -type d -name "themes"
./wp-content/plugins/contact-form-7/includes/js/jquery-ui/themes
./wp-content/plugins/jetpack/modules/infinite-scroll/themes
./wp-content/plugins/smart-youtube/themes
./wp-content/plugins/wptouch-pro/themes
./wp-content/themes
./wp-includes/js/tinymce/themes
cdd
함수가 가장 가까운 결과로 내려가기를 원합니다 . 이 예에서는 입니다 ./wp-content/themes
.
답변1
이를 통해 zsh
다음을 수행할 수 있습니다.
cdd() cd -- **/$1(/Od[1])
cdd themes
이 cdd
기능은 모든 유형의 파일을 찾습니다.목차( /
) 에 인수로 제공된 이름을 사용하여 epth별로 정렬 $1
하고 첫 번째 항목( )을 선택합니다.O
d
[1]
D
비효율적인 점은 현재 디렉터리에 일치하는 디렉터리가 있더라도 전체 디렉터리 트리를 크롤링한다는 것입니다(숨겨진 디렉터리를 건너뛰고 변경하기 위해 glob 한정자를 추가함).
한 번에 한 수준씩 디렉터리 트리를 탐색하려면 다음을 수행할 수 있습니다.
cdd() {
local dirs matches
dirs=(.)
while (($#dirs)) {
matches=($^dirs/$1(N/[1]))
if (($#matches)) {
cd $matches[1]
return
}
dirs=($^dirs/*(/N))
}
print >&2 Not found
return 1
}
답변2
별칭은 중간에 매개 변수를 허용할 수 없고 끝에서만 허용하므로 이 문제를 해결하기 위해 및 별칭을 사용할 수 없습니다. 이를 달성하려면 기능이 필요합니다.
다음 기능이 귀하의 요구 사항을 충족할 수 있습니다.
cdd() {
cd `find . -type d -name "$1"|head -n1`
}
로그인할 때 이 줄이 한 번 실행되도록 .profile(또는 .bashrc 파일)에 이 줄을 추가해야 합니다.
테스트를 위해 이를 이라는 파일에 넣은 다음 func.sh
가져오면(즉, "." 연산자를 사용하여 실행) 환경의 일부가 됩니다.
. ./func.sh
참고: 파일을 변경한 경우 func.sh
해당 파일을 다시 가져와야 합니다.
그런 다음 다음과 같이 사용할 수 있습니다.
cdd <dirname>
이제 함수는 <dirname>
현재 경로와 그 이름을 가진 디렉터리 아래를 검색하고, cd
찾은 첫 번째 일치 항목( head -n1
)을 검색합니다.
find
처음에 원하는 결과를 얻기 위해 작업을 세부적으로 조정할 수 있습니다 . 바라보다 man find
.
가장 가까운 일치 항목을 찾으려면 find 출력을 정렬하여 가장 짧은 줄을 제공할 수 있습니다.
find . -type d -name "$1"| awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2- | head -n1
(이 awk
명령은 다음에서 도난당했습니다.여기.)
이것은 find의 출력에서 가장 짧은 줄을 반환합니다. 그러나 디렉터리를 찾고 있는데 proj
다음과 같은 구조가 있으면 잘못된 디렉터리가 반환됩니다.
./d1/d2/d3/proj
./longdirname/proj
또는 결과의 문자 수를 세어 /
이 문제를 해결할 수 있습니다.
답변3
find
이 bash 기능은 현재 디렉터리의 모든 디렉터리 계층에 대해 무차별 대입 크래킹을 수행하고 지정된 디렉터리를 검색합니다.
cdd() {
if [ "$#" -ne 1 ]
then
printf '%s: Error: one directory name expected\n' "${FUNCNAME[0]}" >&2
return
fi
maxdepth=$(find . -type d -exec sh -c 'printf %s "$1" | LC_ALL=C tr -dc / | wc -c' findshell {} \; | sort -n | tail -1)
for((i=1; i <= maxdepth; i++))
do
dir=$(find . -mindepth "$i" -maxdepth "$i" -type d -name "$1")
if [ -n "$dir" ]
then
command cd -- "$dir"
return
fi
done
printf '%s: %s: no such directory found\n' "${FUNCNAME[0]}" "$1" >&2
}
첫 번째 find
명령은 현재 디렉토리 아래의 각 디렉토리에 대해 쉘 조각을 실행합니다. 쉘 조각은 디렉토리 이름을 tr
& wc
파이프에 인쇄하여 슬래시가 아닌 모든 문자를 제거한 다음 슬래시 수를 계산합니다. 나는 이 기술을 ilkkachu와 Stéphane Chazelas에게서 배웠습니다.여기. 모든 디렉토리 깊이를 출력한 후 sort | tail
가장 큰 숫자를 찾습니다. 이 숫자는 검색해야 하는 최대 디렉터리 깊이입니다.
find
그 후 현재 디렉터리부터 시작하여 가장 깊은 디렉터리까지 차례로 각 디렉터리의 깊이를 제한하는 루프입니다 . 일치하는 항목이 발견되면 cd
함수를 종료합니다. 일치하는 항목이 없으면 루프를 종료하고 stderr에 메시지를 인쇄합니다.
답변4
bash의 재귀 와일드카드 기능을 사용할 수도 있습니다.
shopt -s globstar # in ~/.bashrc, or just in cdd() {}
cd **/structure/
**
확장은 조회와 거의 동일한 순서로 발생하므로 대부분 동일한 문제가 존재한다고 생각합니다 . 하지만 너무 간단하고 유용해서 간과할 수도 있습니다!
여러 매개변수가 있는 bash
거부의 최신 버전cd
따라서 이는 일치하는 항목이 하나만 있는 경우에만 작동합니다. 그렇지 않으면 당신은 얻을 것이다 cd: too many arguments
.
따라서 쉘 기능이 필요합니다. array=( **/"$1"/ )
비어 있지 않은 경우 첫 번째 요소가 사용될 수 있지만 함수를 작성하는 경우 find -depth -type d | tail -1
마지막 결과(가장 얕은 결과 중 하나)를 얻기를 원할 수도 있습니다. 또는 -maxdepth
나무가 상당히 깊을 것 같으면 단계별로 사용하십시오.