zsh - 如何在叶目录运行脚本?

zsh - 如何在叶目录运行脚本?

我有这样的文件夹结构

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

我希望将图像组合成 pdf 的脚本在叶目录中运行

答案1

  • 通配符模式对于文件在递归遍历所有子目录:**/*
  • 要仅选择目录,请添加全局限定符 /:**/*(/)
  • 除非您glob_dots打开了该选项,否则请添加 glob 限定符D以包含以点开头的匹配项。
  • 添加 glob 限定符N以允许匹配列表为空:**/*(/DN)

现在您已经有了子目录列表,要仅获取叶目录,请检查每个目录以查看它是否没有子目录:检查是否*(/DN)为空。您可以添加 glob 限定符Y1以停止在第一个之后列出匹配项。

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。因此,该解决方案不适用于这些文件系统。

有关的:

相关内容