다음과 같은 폴더 구조가 있습니다.
|_folder1
| |_folder1.1
| | |_folder1.1.1
| | |_img00
| | |_...
| |_folder1.2
| |_img00
| |_...
|_folder2
|_img00
|_...
이미지를 PDF로 결합하는 스크립트를 리프 디렉토리에서 실행하고 싶습니다.
답변1
- 와일드카드 패턴파일의 경우모든 하위 디렉터리를 재귀적으로 탐색:
**/*
- 디렉토리만 선택하려면 다음을 추가하십시오.글로벌 예선
/
:**/*(/)
glob_dots
이 옵션을 설정 하지 않은 경우D
점으로 시작하는 일치 항목을 포함하려면 glob 한정자를 추가하세요.N
일치 목록을 비워두려면 glob 한정자를 추가하세요 .**/*(/DN)
이제 하위 디렉터리 목록이 있으므로 리프 디렉터리만 가져오려면 각 디렉터리에 하위 디렉터리가 없는지 확인하고 *(/DN)
비어 있는지 확인하세요. Y1
첫 번째 일치 항목 이후에 일치하는 일치 항목이 나열되는 것을 중지하려면 glob 한정자를 추가할 수 있습니다 .
for d in **/*(/DN); do
sub=($d/*(/DNY1))
if (($#sub)); then continue; fi
process_leaf_directory $d
done
대부분의 파일 시스템에는 더 쉬운 방법이 있습니다. 즉, 리프 디렉터리의 링크 수는 2입니다( .
상위 디렉터리와 해당 항목의 항목만 포함하는 반면, 리프가 아닌 디렉터리에는 ..
하위 디렉터리의 항목도 포함함). 이렇게 하면 필터링이 더 간단해집니다. glob 한정자를 사용하여 링크 수가 2인지 확인하세요 l
.
for d in **/*(/DNl2); do
process_leaf_directory $d
done
답변2
다음 find
명령은 현재 디렉터리 아래의 모든 리프 디렉터리를 찾아 그 안에 있는 스크립트를 실행합니다.
find . -type d -links 2 -execdir /path/to/script.sh some arguments here \;
-execdir
그러면 현재 디렉터리 아래의 모든 리프 디렉터리에 지정된 명령이 실행됩니다.
동일하지만 다음을 사용합니다 zsh
(숨겨진 이름 무시).
for dirpath in ./**/*(/l2); do
( cd "$dirpath" && /path/to/script.sh some arguments here )
done
패턴은 ./**/*(/l2)
현재 디렉터리 아래의 모든 리프 디렉터리의 경로 이름으로 확장됩니다. **
디렉토리 구조를 재귀적으로 일치시키며 *(/l2)
링크 수가 정확히 2인 디렉토리 이름을 일치시킵니다(즉, 하위 디렉토리가 없는 디렉토리이며 find
이는 위 명령에서도 사용됩니다).
일부 파일 시스템(예: Apple의 APFS)에서는 하위 디렉토리가 없더라도 디렉토리의 링크 수가 2보다 클 수 있습니다. BTRFS에서 디렉터리의 링크 수는 항상 1입니다. 따라서 이 솔루션은 이러한 파일 시스템에서는 작동하지 않습니다.
관련된: