트리에서 모든 종료 하위 디렉터리를 찾습니다.

트리에서 모든 종료 하위 디렉터리를 찾습니다.

다음과 같은 구조를 고려하면:

oz123@debian:~/ $ tree .
.
├── a
│   ├── a1
│   ├── a2
│   └── a3
├── a1
│   ├── a11
│   ├── a12
│   └── a31
├── b
│   └── b1
│       ├── b11
│       │   └── b21
│       │       └── b31
│       ├── b12
│       └── b3
└── c

16 directories, 0 files

모든 끝 노드를 찾는 방법은 무엇입니까?

다음 해결책을 찾았습니다.~인 것 같다괜찮습니다. 하지만 어떤 테스트 케이스도 실패하지 않는다는 것을 증명해야 합니다.

상태 도움말 페이지 -links:

"-links"를 사용하여 특정 수의 링크가 있는 파일을 검색할 수도 있습니다. 디렉토리에는 일반적으로 두 개 이상의 하드 링크가 있습니다. 항목은 두 번째 항목입니다. 하위 디렉터리가 있는 경우 각 하위 디렉터리에는 상위 디렉터리에 대한 ..이라는 하드 링크도 있습니다. 이것. 및 .. 디렉토리 항목은 일반적으로 find 명령줄에 언급되지 않는 한 검색되지 않습니다.

가능한 해결책:

oz123@debian:~/ $ find .  -type d  -links 2
./a/a2
./a/a3
./a/a1
./c
./a1/a31
./a1/a11
./a1/a12
./b/b1/b12
./b/b1/b3
./b/b1/b11/b21/b31
  • 누구든지 더 나은 솔루션을 제공할 수 있습니까(이미 성능이 뛰어난 파이프 및 sed를 사용하지 않고...)
  • 모든 파일 시스템에서 작동합니까?

답변1

더 확실한 옵션이 있습니다 -empty.

find . -type d -empty

고쳐 쓰다. 글쎄요, 당신 말이 맞습니다. 이 방법은 디렉토리에 있는 파일에는 작동하지 않습니다.

따라서 고정된 파일 시스템의 신뢰할 수 없는 버전은 다음과 같습니다.

find dtest/ -type d -exec sh -c "if [ \$(find {} -maxdepth 1 -type d | wc -l) -eq 1 ]; then echo {} ; fi" \;

답변2

귀하의 솔루션을 보완하기 위해 -linksUnix 디렉터리 연결 규칙을 따르지 않는 파일 시스템에서는 작동하지 않는다는 점을 덧붙이고 싶습니다. man find옵션을 살펴보면 -noleaf최소한 CD-ROM, MS-DOS 파일 시스템 및 AFS 볼륨 마운트 지점이 있습니다.

참고로 이 문제는 실제로 더 느리고 일반적으로 sed/awk 및 유사한 파이프에 의존하는 다양한 솔루션으로 논의되었습니다.

답변3

find . -type d -links 2대부분의 파일 시스템에서 작동하지만 전부는 아닙니다. 어떤 파일 시스템 유형이 디렉토리에 자체 링크가 포함되어 있는지 아는 것 외에는 알 수 있는 방법이 없다고 생각합니다. GNU find는 이를 동적으로 감지합니다("find의 -noleaf 옵션을 자동으로 켜기"에 대한 내용이 인쇄되면 파일 시스템에 이 속성이 없다는 것을 알 수 있습니다). 가장 일반적인 파일 시스템 유형은 작동하지만 FAT 또는 btrfs는 작동하지 않습니다.

확실하게 확인하려면 각 디렉터리를 테스트해야 합니다. 이를 수행하는 한 가지 방법은 find각 하위 디렉터리를 다시 호출하는 것입니다.

find . -type d ! -exec sh -c '
   find "$1/." ! -name . -type d -prune | grep -q "^"' sh {} \; -print

(GNU를 사용하면 더 효율적 으로 find대체할 수 있습니다 .)-prune-print -quit

또 다른 접근 방식은 의 출력을 후처리하는 것입니다 find. 의 경우 find -depth리프 디렉터리는 자체 하위 디렉터리가 뒤에 오지 않는 디렉터리입니다.

find . -depth -type d -print0 |
awk -v RS='\0' '
    substr(previous, 1, length($0) + 1) != $0 "/"
    { previous = $0 }
'

답변4

다음 해결 방법을 시도해 보십시오(Linux, Unix 및 OS X와 ​​호환되어야 함).

find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' ';'

그 방법은 다음과 유사합니다.비상 해결책, 그러나 파이프는 없습니다.

관련 정보