在Bash中循环遍历目录

15

我需要这个脚本能够cd到一个目录,然后删除子目录中除了几个特定文件以外的所有文件,但不要删除文件夹。使用switch/case语句来保留需要保留的每个文件是否有帮助?

理想情况下,我认为它应该继续搜索更深层次的子目录,而不是我嵌套搜索两级目录。

另一个问题是它会跳过有空格的文件夹(尽管目前对于脚本将运行的卷没有问题)。

这是我的代码:

for i in /Users/YourName/Desktop/Test/* ; do
  if [ -d "$i" ]; then
    cd $i

    for j in "$i"/* ; do
      if [ -d "$j" ]; then
        cd $j

        for k in $(ls *); do
          if [ ! $k == "watch.log" ]; then
            echo $k
            rm -rf $k
          fi
        done

      fi
    done

  fi
done

不要猜测出了什么问题,确保是“cd”命令有误,我们不能猜测。 - Mat
使用 rm -rf 命令不仅可以删除文件,还可以删除(子)目录。但是根据您的问题和所包含的源代码进行比较,我并不确定您想要做什么... - aurora
抱歉,Mat。我在写这篇帖子时不小心按了回车键,这篇草稿是关于一个已经解决的旧问题。谢谢。 - infmz
谢谢Herald。是的,我忘记了rm -r触发器。我肯定需要重写脚本并发布。 - infmz
3个回答

32

你应该使用find

for i in $(find . -type d)
do
    do_stuff "$i"
done
如果你有很多目录,可以将find的输出传输到一个while read循环中,但这会使编码更加困难,因为该循环在另一个进程中运行。关于空格,请确保引用包含目录名称的变量。这样可以处理名称中带有空格的目录。

1
谢谢。我真的需要更熟悉find命令。 - infmz
如果目录名称中包含空格字符,这将会出错。 - codeforester
1
循环查找被认为是脆弱的。更多信息请参见https://github.com/koalaman/shellcheck/wiki/SC2044 - Kishan B

12

这个怎么样?

$ find /Users/YourName/Desktop/Test -type f -maxdepth 2 -not -name watch.log -delete

说明

  • -type:只查找文件
  • -maxdepth:最多向下遍历两级目录
  • -not -name(组合):从搜索中排除watch.log
  • -delete:删除文件

建议

首先尝试在命令行中使用上述命令但不加-delete标志。这将显示将被删除的文件列表。

一旦您满意该列表,再将-delete添加到命令中。


这个很棒!我唯一的担心是它也会捕捉到 .files,但我猜这很容易实现。非常感谢 - 你把我的脚本变成了一行!我真的需要学习这些命令。 - infmz

2

使用find命令?您可以使用多个参数,包括深度、文件年龄(如stat)、权限等...

find . -maxdepth 2

你的整个脚本可以用单行执行。查看 find 命令的 -maxdepth-mindepth-name-exec 选项。如果我正确理解你的意图,应该是这样的:find /Users/YourName/Desktop/Test -mindepth 2 -name "watch.log" -exec rm -rf {} \; -prune - Chen Levy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接