如何对子目录递归运行 ZSH glob 命令

如何对子目录递归运行 ZSH glob 命令

我有一个 ZSH glob 命令,可以删除文件夹中除最新 10 个目录之外的所有内容。

#! /bin/zsh
cd /path/to/backups/pod1 && rm -rf ./*(Om[1,-11])

但是,这仅限于 pod1 目录。我在同一级别有许多备份目录,即 pod1、pod2、pod3 等...理想情况下,我希望有一个像这样的通配符:

cd /path/to/backups/* && rm -rf ./*(Om[1,-11])

...这将按照上述方式在备份的任何子目录中执行 glob 命令。

但是,当我运行它时,我收到以下消息:

cd: too many arguments

所以我不太确定该怎么做。

答案1

cd只接受一个参数。一种方法是cd进入每个目录(使用子 shell,尽管这不是必需的假如这些目录都是完全限定的(也就是说,目录不是相对的))

for d in /path/to/backups/*; do
  ( cd $d && rm -rf ./*(om[1,-11]) )
done

另一种方法是直接删除文件(此处进行调试print以首先确认已匹配正确的文件),因为可以在表达式中指定多个 glob。请注意,这总共保留 10 个文件,而基于循环的解决方案在每个目录中保留 10 个文件。

print -l /path/to/backups/pod*/*(Om[1,-11])

然而,如果匹配太多文件,这可能会遇到 shell 限制,在这种情况下可能需要xargsZSH 。zargs

答案2

我不知道这是否有帮助,但是 - 由于这个问题有点老 - 希望这至少可以为未来的读者提供一些帮助:

该命令查找(实际命令的名称是 find) 每个末尾带有*通配符 [点] 扩展名的文件。

find . -name <*.Extension> -type f -exec < command > {} \;

在哪里:

  • .或者 -./标记当前目录,使用类似的东西 /home/you/Folders/Files/来处理给出的命令仅位于 Files/ 文件夹下的文件。与,<通配符扩展名>。
  • <*.扩展名>是文件通配符扩展名,例如*.dll*.doc
  • <command>是对所有找到的文件执行的命令,例如md5sum计算具有指定 .Extension 的每个文件的 md5 校验和。

示例1:

对每个以 a 结尾的文件执行head -n 50命令| sha256sum

.F0扩展名,并将输出保存在文件中Result.out

find . -name *.F0 -type f -exec head -n 50 {} \; | sha256sum >> Result.out

示例2:

与上面相同,但使用环境变量:

EXT="*.F0"

CMD="head -n 50"

find . -name $EXT -type f -exec $CMD {} \; | sha256sum >> Result.out

相关内容