일치하는 디렉토리에서 한 레벨 깊이의 디렉토리 목록 찾기


13

특정 폴더에 포함 된 디렉토리 목록을 가져 오려고합니다.

다음 예제 폴더가 제공됩니다.

foo/bar/test
foo/bar/test/css
foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

반환 할 명령을 원합니다.

XYZ
ABC
DEF
GHI

기본적으로 wp-content / plugins / 안에있는 폴더를 찾고 있습니다.

사용 find하는 것이 가장 가깝습니다.하지만 -maxdepth폴더가 검색하는 위치와 가변적이므로을 사용할 수 없습니다 .

다음을 실행하면 모든 하위 디렉토리가 재귀 적으로 리턴됩니다.

find -type d -path *wp-content/plugins/*

foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

답변:


14

-prune찾은 디렉토리가 다음으로 내려 가지 않도록 그냥 추가하십시오 .

find . -type d -path '*/wp-content/plugins/*' -prune -print

*wp-content/plugins/*쉘 글로브이므로 인용해야합니다 .

GNU와 함께, 자신의 전체 경로에 반대 만 디렉토리 이름을 원하는 경우에 find, 당신은 대체 할 수 -print-printf '%f\n'나에 파이프를, 파일 경로가 개행 문자를 포함하지 않는 위의 명령의 출력을 가정 awk -F / '{print $NF}'하거나 sed 's|.*/||'또한 파일의 경로가 포함 된 가정 ( 유효한 문자 만).

zsh:

printf '%s\n' **/wp-content/plugins/*(D/:t)

**/하위 디렉토리의 모든 수준이다 (의 기능 원래 zsh초기 nighties에, 그리고 지금은 좋아 대부분의 다른 껍질에서 발견 ksh93, tcsh, fish, bash, yash하지만 일반적으로 몇 가지 옵션 아래) (/)형식의 파일 만 선택 디렉토리 , D숨겨진 (점) 사람을 포함하는, :t꼬리 (파일 이름)를 얻습니다 .


이 찾기는 dirs의 개행을로 변환합니다 ?. bash의 경우 (질문에 태그가 지정된) 작동합니다 .
Isaac Isaac

@sorontar, 인쇄 할 수없는 문자에 대한 대체 문자 또는 이스케이프 형식 find을 출력하는 구현은 출력이 여기에있는 파이프로 이동할 때가 아니라 터미널로 이동할 ?때만 수행합니다.
Stéphane Chazelas

대답에있는 첫 번째 (및 비 zsh) 명령에는 파이프가 없으며 테스트 한 것이고 줄 바꿈을 변경하는 명령입니다. 파이프로 말하면 "파일 경로에 줄 바꿈 문자가 없다고 가정"하면 줄 바꿈으로 실패한다는 것을 이미 인정했습니다.
Isaac Isaac

@sorontar, 미안 해요 당신이 줄 바꿈이 우리가하고있는 가정이 손상되지 그래서 이스케이프 것으로 확인 작업 것이라는 말을 두 번째 부분에 주석 줄 알았는데 sed/ awk모든 파일이 온라인에 있는지를. 이제, 하나는 점점 주장 할 수 있습니다 ABC?BCD또는 ABC\nBCD대화 형 / 터미널 출력하는 것은이 점점 더 유용 할 것이다 ABCBCD라는 디렉토리에 대한 라인 $'ABC\nBCD. 그것은 사용자 프리젠 테이션 수준에서, 우리는라는 파일의 $'AB\bC'경우, 출력이 터미널로 갔을 때 AC그러한 ?대체 없이 볼 수 있음을 지적 할 수 있습니다 .
Stéphane Chazelas

-prune을 사용하여 printf를 사용하여 출력 형식을 수정하면 정확히 내가 원하는 것을 얻었습니다. 완벽합니다-감사합니다!
Nick

4

돌진 적으로 :

shopt -s globstar
printf "%s\n" **/wp-content/plugins/*

인쇄물:

bat/bar/foo/blog/wp-content/plugins/GHI
baz/wp-content/plugins/ABC
baz/wp-content/plugins/DEF
foo/bar/wp-content/plugins/XYZ

또는

shopt -s globstar
for d in **/wp-content/plugins/*; do printf "%s\n" ${d##*/}; done

인쇄물:

GHI
ABC
DEF
XYZ

아니, 그것은 dirs 내부의 파일도 인쇄합니다. 내 대답을 읽으십시오.
Isaac

좋은 지적; 감사합니다! 디렉토리 구조를 다시 만들었지 만 테스트 파일을 넣지 않았습니다.
Jeff Schaller

4

당신은 find재귀를 할 수 있습니다 .

find / -type d -path *wp-content/plugins -exec find {} -maxdepth 1 -mindepth 1 -type d \;

3

Bash : Simple ( 공백 과 줄 바꿈이있는 파일 / 디렉토리에서 작동 ) :

shopt -s globstar                    # allow ** for several dirs.
a=(**/wp-content/plugins/*/)         # capture only wanted dirs.
a=("${a[@]%/}")                      # remove trailing slash (dirs) `/`.
printf '%s\n' "${a[@]##*/}"          # print only the last dir name.

Wll 인쇄 :

GHI
ABC
DEF
XYZ

파일이 생성 된 경우에도 마찬가지입니다.


숨겨진 디렉토리 내부를 보지 않고 숨겨진 파일을 건너 뛰고 ( dotglob원치 않는 경우 옵션 참조 ) 디렉토리 외에도 디렉토리에 대한 심볼릭 링크를 포함합니다 ( **bash 4.2 이하의 심볼릭 링크를 통과합니다).
Stéphane Chazelas

@ StéphaneChazelas 숨겨진 파일? 질문은 아무 것도 요구하지 않으며 단지 찌르기 만합니다. 예, 숨겨진 디렉토리는 독립적으로 선택할 수 있습니다 (원하는 경우 기능으로). 그리고 예, 현재 버전의 bash에서는 심볼릭 링크가 가로 방향이 아닙니다.
Isaac Isaac

1
내 의견을 침략으로 간주하지 마십시오. 나는 당신의 대답을 상향 조정하고 그 아래에 메모가 추가되어 반드시 분명하지 않은 사실을 지적했습니다. find파일을 제외하지 않습니다. globs는 도트 파일을 제외하고 둘 사이의 차이점으로 지적 할 가치가 있습니다.
Stéphane Chazelas

3

tree명령은이 목적을 위해 정확하게 설계되었습니다. -L플래그로 깊이를 제어 할 수 있습니다 . 다음은 내가 관리하는 로컬 Wordpress 사이트의 예입니다.

$ tree -L 1 wp-content/
wp-content/
├── index.php
├── plugins
└── themes

2 directories, 1 file

$ tree -L 2 wp-content/
wp-content/
├── index.php
├── plugins
   ├── akismet
   ├── contact-form-7
   ├── index.php
   └── wordpress-seo
└── themes
    ├── index.php
    ├── twentyfifteen
    └── twentysixteen

11 directories, 3 files

$ tree -L 1 wp-content/plugins/
wp-content/plugins/
├── akismet
├── contact-form-7
├── index.php
└── wordpress-seo

5 directories, 1 file

1

DopeGhoti의 답변을 바탕으로 일치하는 루프는 어떻습니까?

find / -type d -iregex '.*/wp-content/plugins' -print0 | while read -r -d $'\0' D; do
    find "$D" -maxdepth 2 -mindepth 1
done

이 방법을 사용하는 이유는 -exec\ n ''등을 포함하는 고유 한 파일 이름 문제를 피하는 동안 여러 개의 파일을 혼동하고 혼란스럽게 만들 수 있기 때문입니다 . -print0은 결과 사이에 널 구분 기호를 사용합니다.


0

시작한 것을 바탕으로 :

find -type d -path *wp-content/plugins/* | egrep -o "wp-content/plugins/[^/]+($|/)" | sed -r "s~wp-content/plugins/([^/]+)($|/)~\1~" | uniq  

egrep은 * wp-content / plugins / * 및 다음 슬래시 또는 줄 끝 $까지의 문자를 가져옵니다. 여기에는 원하는 부분이 포함됩니다.

~ 구분 기호가있는 sed 는 첫 번째 괄호 ()를 사용하여 원하는 부분을 선택하고 \ 1 (원하는 것)을 모든 것을 대체합니다.

uniq 중복 결과를 필터링

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