使用 find 和 exec 提高脚本的性能

使用 find 和 exec 提高脚本的性能

我有一个脚本,它会遍历给定的目录,并自动压缩那些不包含至少一个在 30 天内使用过的文件的目录。现在,我想知道是否可以通过将 find 与 exec 一起使用来提高性能。我尝试了一些东西,但它不起作用。你有什么建议吗?

#!/bin/bash
# find all the directories
dirs=`find . -type d`
# iterate every file in every directory
for dir in $dirs
do
        n="totar"
        # search all the file in the directory
        files=`find $dir -type f -atime -30`
        for file in $files
        do
                n="keepasis"
        done
        if [ $n == "totar" ]; then
                tar -zcvf $dir.tgz $dir
                rm -r $dir
        fi
done

我的想法是将第二个 for 循环替换为以下内容:

find $dir -type f -atime -30 -exec n="keepasis" {} \;

答案1

find如果您在的操作中设置变量,-exec则该变量将不可见。

找到文件并打印其名称这一事实find足以决定您不想存档该目录。所以你不需要循环for file in $files,而是检查它$files不为空。

如果您的find命令支持该-quit操作,您可以使用它在第一个匹配后停止。 (看如何在第一次匹配后停止查找命令?

不要将第一个的输出放入find变量中并使用带有分词功能的 for 循环,您应该更好地逐行读取findLime 的输出。

#!/bin/bash
# find all the directories
# -mindepth 1 prevents "find" from printing "."
find . -mindepth 1 -type d | while read -r dir
do
    # a subdirectory might no longer exist if a parent has been archived before
    if [ -d "$dir" ]
    then
        # search any new file in the directory
        newfilefound=`find $dir -type f -atime -30 -print -quit`

        if [ -z "$newfilefound" ]
        then
            tar -zcvf $dir.tgz $dir
            rm -r $dir
        fi
   fi
done

如果您使用的是 bash,您可以改进第一个find以正确处理更多带有特殊字符的目录名称:find . -type d -print0 | while IFS= read -r -d '' dir; do...

仍然存在一个性能问题:

如果目录的子目录中某处包含新文件,则不要将其删除。稍后您将获得包含此文件的所有子目录名称。在这种情况下,您将使用find多次来查找相同的新文件。

我想到的唯一解决方案是使用两个find,一些后处理和一个fgrep

  1. 让我们find打印所有新文件的名称,通过删除文件名、将所有父目录打印为单独的行、删除重复项并将列表放入文件 NEWDIRS 来处理输出。
  2. 第二次将find所有目录名称打印到第二个文件 ALLDIRS.
  3. 用于fgrep查找 ALLDIRS 中与 NEWDIRS 中的行不匹配的所有行。

tar在删除目录之前,您应该检查命令是否成功。

相关内容