脚本

脚本

目前,我正在做完整的手工工作。

find /home/bash_cookbook/bash_cookbook/glassfish/domains/blog/logs -mtime +7 -type f -name 'application.log_*' -exec rm {} \;

仅输入我要遍历的所有目录名称就花了我 1 个小时。

问题?

有100多台服务器,每台服务器中有20个不同的域,每个域都有不同的域名称。我想到的一个聪明的方法是排除某些目录而不是包含所有目录。因为其中一些包含一些域,例如我不需要触及的“备份”。

但我不知道如何实现它。


我能想到的另一个巧妙的技巧是这个。

find /home/bash_cookbook/bash_cookbook/glassfish/domains/$domains_except_excluded_domains/logs -mtime +7 -type f -name 'application.log_*' -exec rm {} \;

为此,我需要domains_ except_excluded_domains 变量,该变量需要包含我想要排除的所有域。如何才能实现这一目标?

答案1

如果您正在使用bash或其他支持数组的 shell,您可以列出要包含的域集以进行处理:

#!/bin/bash
incDomains=('blog' 'news' 'webmail' …)

for domain in "${incDomains[@]}"
do
    echo "Considering $domain"
    find "/home/bash_cookbook/bash_cookbook/glassfish/domains/$domain/logs" -mtime +7 -type f -name 'application.log_*' -delete
done
echo "Done"

我猜测$domain变量应该插入到find路径中的位置。根据需要移动它。

你可以使用类似的东西排除域(如果您确定能够安全地枚举它们)。此方法从要排除的域列表开始,将它们转换为关联数组(哈希)以进行快速查找,然后遍历域目录集,跳过哈希中的任何目录:

#!/bin/bash
excDomains=('blog' 'news' 'webmail' …)

declare -A excDomainsH
for domain in "${excDomains[@]}"; do excDomainsH[$domain]=1; done

for domainPath in "/home/bash_cookbook/bash_cookbook/glassfish/domains"/*
do
    domain="${domainPath##*/}"
    [[ "${excDomainsH[$domain]}" -eq 1 ]] && continue

    echo "Considering $domain"
    find "$domainPath/logs" -mtime +7 -type f -name 'application.log_*' -delete
done
echo "Done"

在这两种情况下我都会强烈推荐-delete直到您-print确定代码按预期工作为止。如果您的实现find没有-delete考虑使用-exec rm -f {} +(请注意+最后)

答案2

为了排除整个目录,一个选项是负面匹配路径:

find ! -path '*exclude1*' ! -path '*exclude2*' ...

与 相比-name-path可以包含斜杠并且不会特殊对待斜杠。

如果您的主要问题是速度,原因可能不是搜索目录太多,而是每个文件-exec rm {}\;调用一次。rm只需将其替换为-delete.另请阅读有关和man find之间的区别 ,其中后者将使用尽可能多的结果作为命令参数列表。-exec command {}\;-exec command {} +

答案3

这是我对这个问题的尝试。

脚本

#!/bin/bash
given_path=/home/techyman/glassfish4/glassfish/domains
excluded_folder=x
for each in $(ls $given_path); do
    if [ "$excluded_folder" = "$each" ]; then
        echo "This is x"
        continue
    else
        echo "this is not x"
        cd $given_path/$each/logs
        echo "This is $PWD"
    fi
done

它能做什么

  • 这将转到给定的路径。
  • ls 列出列表吗
  • 如果 ls 等于排除的文件夹,它将使用 continue 语句跳过它
  • 否则它会进入日志目录并执行一些操作。

更新:

#!/bin/bash
given_path=/home/techyman/glassfish4/glassfish/domains
excluded_folder=x
for each in "$given_path"/*; do
    if [ "$excluded_folder" = "$each" ]; then
        echo "This is x"
        echo "$PWD"
        continue
    else
        echo "this is not x"
        echo "$PWD"
        cd $each/logs
        # echo "This is $PWD"
        # echo "This is $x"
    fi
done

更新

#!/bin/bash

given_path=/home/techyman/glassfish4/glassfish/domains
excluded_folder="x"
function clear_log() {
    cd "$each"
    echo "$PWD"
    find . -mtime +"$1" -name "*.log" -exec rm -f {} \;
    #echo "$2"
    #echo "$1"
}
for each in "$given_path"/*; do
    if [ "$each" = "$given_path/$excluded_folder" ]; then
        echo "$each"
        #echo "This is x"
        #echo "Do nothing"
        continue
    else
        #echo "this is not x"
        #echo "$each"
        #case statement goes here
        case $each in
        *a)

            echo "This is a"
            clear_log 7 "$each"
            ;;
        *b)
            echo "This is b"
            clear_log 4 "$each"
            ;;
        *c)
            echo "This is c"
            clear_log 5 "$each"
            ;;
        *d)
            echo "This is d"
            clear_log 6 "$each"
            ;;
        *e)
            echo "This is e"
            clear_log 8 "$each"
            ;;
        esac
    fi
done

相关内容