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です。したがって、このソリューションはこれらのファイルシステムでは機能しません。

関連:

関連情報