zsh - 리프 디렉토리에서 스크립트를 실행하는 방법은 무엇입니까?

zsh - 리프 디렉토리에서 스크립트를 실행하는 방법은 무엇입니까?

다음과 같은 폴더 구조가 있습니다.

|_folder1
| |_folder1.1
| | |_folder1.1.1
| |   |_img00
| |   |_...
| |_folder1.2
|   |_img00
|   |_...
|_folder2
  |_img00
  |_...

이미지를 PDF로 결합하는 스크립트를 리프 디렉토리에서 실행하고 싶습니다.

답변1

이제 하위 디렉터리 목록이 있으므로 리프 디렉터리만 가져오려면 각 디렉터리에 하위 디렉터리가 없는지 확인하고 *(/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입니다. 따라서 이 솔루션은 이러한 파일 시스템에서는 작동하지 않습니다.

관련된:

관련 정보