다른 하위 디렉토리가 없는 디렉토리만 나열하려면 어떻게 해야 합니까?
목록에만 /A /A/AA /A/AB /A/AB/ABB /B /C /C/CC /C/CC/CCC /C/CC/CCC/CCCC
사용하고 싶은 구조를 상상해 보세요 .find
/A/AA /A/AB/ABB /B /C/CC/CCC/CCCC
시작점은 이지만 find . -type d
둘 중 하나도 사용할 수 -mindepth
없으며 도움이 될 수 있습니까(원하는 방식으로 반응하도록 할 수 없습니다)?-maxdepth
-noleaf
답변1
find
다음은 나열된 하위 디렉터리가 있는 디렉터리를 제거하기 위해 출력을 후처리하는 POSIX 호환 솔루션입니다 . 디렉터리 이름에 개행 문자가 없다고 가정합니다.
{ find . -type d; echo; } |
awk 'index($0,prev"/")!=1 && NR!=1 {print prev}
1 {sub(/\/$/,""); prev=$0}'
설명: awk 스크립트는 다음 줄을 읽을 때까지 각 줄의 인쇄를 지연하고 접두사가 아닌 경우에만 이전 줄을 인쇄합니다. 이는 find
상위 디렉터리 바로 뒤에 하위 디렉터리가 나열된다는 사실을 활용합니다 . 추가 기능은 존재하는 경우 "/"
허위로 제거하는 것을 방지하는 것입니다 . inelegant는 첫 번째 빈 줄을 인쇄하는 것을 피하고 inelegant는 마지막 줄에 똑같이 우아하지 않은 특별한 경우를 갖지 않습니다. 예를 들어 호출된 경우 최상위 디렉토리에서 후행 슬래시를 제거하는 호출입니다 .foo
foobar
NR!=1
echo;
sub
find ./
평소와 같이 비밀스러운 zsh 단일 라이너가 있습니다.
echo **/.(e\''test -z $REPLY/*(/DN[1])'\':h)
더 길고 읽기 쉬운 버전:
is_leaf () { [ -z $REPLY/*(/DN[1]) ] }
echo **/.(+is_leaf:h)
echo **/(+is_leaf)
후행이 마음에 들지 않으면 마지막 줄을 단순화할 수 있습니다 /
.
요약 설명: 괄호 안의 내용은글로벌 한정자, zshexpn
매뉴얼 페이지에 설명되어 있습니다. glob의 결과를 필터링하여 **/
(현재 디렉터리와 모든 하위 디렉터리로 확장) 함수 is_leaf
(또는 사이의 코드 '…'
)가 0을 반환하는 결과만 유지합니다. 필터 코드는 테스트 중인 일치 항목의 하위 디렉터리( $REPLY
)(에서) 를 glob합니다. 사실, [1]
첫 번째 하위 디렉터리 이후에 중지되도록 하고 적어도 하나의 하위 디렉터리가 발견되었는지 여부를 나타내는 상태를 반환합니다. glob 한정자는 /
확장을 디렉터리로 제한합니다. N
일치하는 항목이 없으면 확장이 비어 있음을 의미합니다. D
도트 파일이 포함되도록 합니다. :h
는 기록 수정자이며 /.
접미사가 제거되도록 합니다(일반적으로 를 의미함 dirname
).
zsh의 glob 한정자의 가능성을 설명하기 위해 해당 기능을 갖춘 두 가지 다른 변형(더 길고 더 모호하다고 생각합니다)이 있습니다 is_leaf
.
echo **/.(e\''tmp=($REPLY/*(/DN[1])); ((!#tmp))'\':h)
echo **/.(e\''$REPLY/*(/DN[1]e:REPLY=false:)'\':h)
is_leaf () { set -- $REPLY/*(/DN[1]); ((!#)); }
is_leaf () { return $REPLY/*(/DN[1]e:REPLY=1:) }
답변2
이것이 내가 사용하는 것입니다:
leaf () { find "${1:-.}" -depth -type d | sed 'h; :b; $b; N; /^\(.*\)\/.*\n\1$/ { g; bb }; $ {x; b}; P; D'; }
다음에서 시작하려면 디렉터리를 사용하여 호출하세요.
leaf /start/dir
답변3
하위 디렉터리가 없는 디렉터리를 찾으려면 다음 안내를 따르세요.
find dir -type d -links 2
설명: 디렉토리에는 각 하위 디렉토리에 대한 링크, 상위 디렉토리의 링크, 자체 링크가 있으므로 하위 디렉토리가 없는 경우 링크는 2개입니다.