답변:
다음은 GNU find
와에 기반한 완전히 다른 접근법입니다 uniq
. 이것은 발견 된 각 디렉토리의 파일을 계산하는 쉘 명령을 실행하는 것에 대한 응답보다 훨씬 빠르고 CPU 친화적입니다.
find . -type f -printf '%h\n' | sort | uniq -d
이 find
명령은 계층 구조에있는 모든 파일의 디렉토리를 인쇄하고 uniq
두 번 이상 나타나는 디렉토리 만 표시합니다.
-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
find . -type d \
-exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' \
-print
현재 디렉토리 내 또는 아래에서 모든 이름을 찾은 다음 디렉토리 이름이 아닌 모든 이름을 필터링합니다.
나머지 디렉토리 이름은이 짧은 스크립트에 제공됩니다.
c=0
for n in "$1"/*; do
[ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
done
[ "$c" -ge 2 ]
이 스크립트는 첫 번째 명령 행 인수 (from find
) 로 제공된 디렉토리의 일반 파일 (심볼 링크 건너 뛰기) 수를 계산합니다 . 스크립트의 마지막 명령은 개수가 2 이상인지 확인하는 테스트입니다. 이 테스트의 결과는 스크립트의 반환 값 (종료 상태)입니다.
테스트가 성공하면, -print
원인이됩니다 find
디렉토리의 경로를 출력 할 수 있습니다.
숨겨진 파일 (이름이 점으로 시작하는 파일)도 고려하려면 sh -c
스크립트에서
for n in "$1"/*; do
에
for n in "$1"/* "$1"/.*; do
테스트 :
$ tree
.
`-- test
|-- a
|-- dir1
| |-- a
| |-- b
| `-- c
`-- dir2
|-- dira
|-- dirb
| |-- file-1
| `-- file-2
`-- dirc
6 directories, 6 files
$ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' -print
./test/dir1
./test/dir2/dirb
[ "" -ge 2 ]
유효한 테스트 이므로 디렉토리에 일반 파일이 없으면 오류가 없습니다 .
dash
, bash --posix
그리고 test
모든 디스플레이는 2 오류 메시지 종료 (즉 "는 오류가 발생했습니다")
ksh
실행 되는 시스템에서 테스트하고있었습니다 sh
. 즉시 수정합니다. 나를 파고 주셔서 감사합니다! :-)
[ -f ... ]
심볼릭 링크를 역 참조합니다. 질문에 일반 파일 만 계산되도록 지정되어 있으므로 제거하기위한 테스트를 추가해야합니다.
의 도움으로 질의 대답 에 SU 와 그 역 및 일부 수정이 필요 여기서 뭐.
find . -type d -exec sh -c 'set -- "$1"/*;X=0;
for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ {} \; -print
디렉토리 트리.
.
├── test
│ ├── dir1
│ │ ├── a
│ │ ├── b
│ │ └── c
│ ├── dir2
│ │ ├── dira
│ │ │ └── a file\012with\012multiple\012line
│ │ ├── dirb
│ │ │ ├── file-1
│ │ │ └── file-2
│ │ └── dirc
│ ├── diraa
│ ├── dirbb
│ ├── dircc
│ └── x
│ └── x1
│ └── x2
└── test2
├── dir3
└── dir4
결과:
./test
./test/dir1
./test/dir2/dirb
test
및 dir2
디렉토리를 모두 찾습니다 (내 답변 참조).
test/x1
및 test/x2
뿐만 아니라 파일과 같은 ... $1
와 $2
에 대한 디렉토리 것 test
, 그리고 디렉토리 놓칠 수 있습니다.
또 다른 find
+ wc
접근법 :
find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" \
-exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ {} \; -print
path/currdir
-현재 디렉토리 경로
-maxdepth 1
- 직접 하위 하위 폴더 만 고려
! -empty
-빈 하위 폴더 무시
! -path "path/currdir"
-현재 디렉토리 경로를 무시
count=$(find "$1" -maxdepth 1 -type f | wc -l)
- count
발견 된 각 하위 폴더에 대한 파일 수가 지정됩니다.
[ $count -ge 2 ] ... -print
-2 개 이상의 정규 파일을 포함하는 하위 폴더 이름 / 경로 인쇄
find
. 이 경우, GNUfind
는 현재 로케일에서 인쇄 할 수없는 문자 (C 로케일의 "ä")가있는 디렉토리 이름을 맹 글링 하기 때문 입니다. 참조 unix.stackexchange.com/questions/321697/...