查找所有空目录和具有单个(特定)文件的目录

Dav*_*vid 2 find shell-script

我正在尝试编写一个 shell 脚本,删除所有空目录 \nas\xc2\xa0well\xc2\xa0 作为仅包含.DS_StoreMac 生成的文件的任何目录。\xc2\xa0\nI\xc2\xa0 可以很容易地完成前者和

\n
find -depth -type d -empty\n
Run Code Online (Sandbox Code Playgroud)\n

但 I\xc2\xa0 无法弄清楚如何查找 .DS_Store包含.

\n

有没有一种简单的方法可以做到这一点,而无需编写自己的递归搜索函数?

\n

Gil*_*il' 6

POSIX sh + 查找

\n

这是一个仅依赖于 POSIX find 和 POSIX sh 的解决方案。列出所有目录,然后过滤那些仅包含名为 的条目的目录.DS_Store

\n
find . -type d -exec sh -c \'\n    cd "$0" &&\n    for x in * .[!.]* ..?*; do\n      if [ "$x" = ".DS_Store" ]; then continue; fi;\n      if [ -e "$x" ] || [ -L "$x" ]; then exit 1; fi;\n    done\' {} \\; -print\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • 我用来find递归地枚举所有目录。
  • \n
  • 在每个目录上,我调用sh运行一些 shell 代码。
  • \n
  • for循环枚举目录中的所有文件。
  • \n
  • 循环体会跳过.DS_Store
  • \n
  • 如果这三个模式中的每一个都不与任何文件匹配,则将保持不变。[ -e "$x" ] || [ -L "$x" ]捕获任何文件,包括损坏的符号链接;它们不匹配的唯一原因是模式保持不变。
  • \n
  • exit 1因此,如果存在除 之外的文件,则shell 代码段运行.DS_Store,否则返回 0 表示成功。
  • \n
  • 如果您想要执行除打印姓名之外的其他操作,请更改-print为。-exec \xe2\x80\xa6
  • \n
\n

兹什

\n

这是 zsh 中的解决方案。更改echo为您要运行的任何命令。

\n
setopt extended_glob\necho **/*(/DNe\\\'\'a=($REPLY/^.DS_Store(DNY1)); ((!#a))\'\\\')\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • **/*递归枚举所有文件。
  • \n
  • 使用glob 限定符 /**/*(/)递归枚举所有目录。
  • \n
  • N如果没有匹配项,glob 限定符可确保您得到一个空列表(默认情况下 zsh 会发出错误信号)。
  • \n
  • glob 限定符D会导致包含点文件。
  • \n
  • glob 限定符对每个匹配的文件名运行 ,并将匹配限制为成功的文件名。可以使用变量来引用文件名。e\\\'\'CODE\'\\\'CODECODECODE$REPLY
  • \n
  • ^.DS_Store匹配未调用的文件.DS_Store
  • \n
  • 因此,代码将匹配限制为除文件之外的文件数为零的匹配.DS_Store
  • \n
  • glob 限定符Y1将匹配限制为一次(这只是效率的提高)。
  • \n
\n

Python

\n

这是 Python 中的解决方案(它适用于 2 和 3)。尽管被压缩成一行,但结构还是相当清晰。

\n
python -c \'import os; print("\\n".join([path for path, dirs, files in os.walk(".") if dirs == [] and files in ([], [".DS_Store"])]))\'\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  • os.walk在其参数下递归返回目录列表。对于每个目录,它都会生成一个三元组,其中包含path(目录的路径)、dirs(子目录列表)和files(目录中本身不是目录的文件列表)。
  • \n
  • [\xe2\x80\xa6 for \xe2\x80\xa6 in os.walk(\xe2\x80\xa6) if \xe2\x80\xa6]过滤 的结果os.walk
  • \n
  • if仅当元素没有子目录且除 之外没有文件时,该子句才会保留该元素.DS_Store
  • \n
  • 该脚本打印接受的元素,并在中间和最后一个换行符之间加入换行符。
  • \n
\n