• linux递归遍历并清理目录(2种方法)


    方法一

    shell脚本如下:

    #!/bin/bash
    
    #日志文件路径
    logPath=/var/log/yx.log
    
    echo -e "$(date +%Y%m%d" "%H:%M:%S): 清理程序开始执行!清理规则:A.文件大于100M,且存在时间超过5天;B.模型目录下的子目录存在时间超过30天
    !
    "
    echo -e "$(date +%Y%m%d" "%H:%M:%S): 清理程序开始执行!清理规则:A.文件大于100M,且存在时间超过5天;B.模型目录下的子目录存在时间超过30天!
    " >> $logPath
    
    #计数器,计算总共删除了多少个目录
    dirCnt=0
    #计数器,计算总共删除了多少个文件
    fileCnt=0
    
    function recursive() {
      
      #dir="$1"
      #if [ "$dir" == "" ];then 
      #  echo 请输入一个参数,指定要清理的目录!
      #else
        #currDir=$1
        #判断参数$1,是否以 / 结尾
        #if [[ "$currDir" != */ ]];then
        #  #echo 当前目录/文件:${1%%/}
        #  currDir=$currDir"/"
        #fi
    
        echo -e "当前目录:$1"
        echo -e "当前目录:$1" >>$logPath
        #lines="`ls -l --time-style='+%Y%m%d' $1 | awk '{print $2,$6,$7,$1$8}'`"
        #while循环位于管道中,这意味着在运行过程中,while循环实际是位于一个新的SHELL中的,while循环中的变量和文件开头定义的变量是两个不同的变量,所以while循环中所改变的值在while循环结束后无法保存下来。解决这个问题的方法就是不要使用管道,改用重定向!
        while read line 
        do
          #echo $line
          #oldIFS=$IFS
          #IFS=" "  #设置字符串的分隔符为空格,默认为空格,所以这里不需要设置
          arr=($line)
          #echo "  ${#arr[@]}  ${arr[@]}"
          if [[ "${arr[0]:0:1}" == "d" ]];then
            #文件创建/修改日期距离当前日期的天数
            diffDays=$((($(date +%s) - $(date +%s -d ${arr[2]}))/86400))
            #判断当前目录是否是模型目录下的子目录,比如/data/xwd/20191102/,且存在时间超过30天,超过则删除
            if [[ "${arr[3]}" =~ ^[0-9]{4}(0[0-9]|1[12])([012][0-9]|3[01])$ && $diffDays -gt 30 ]];then
              rm -rf $1/${arr[3]}
              echo "    $1/${arr[3]}:该目录存在时间超过30天,删除之"
              echo "    $1/${arr[3]}:该目录存在时间超过30天,删除之" >> $logPath
              let dirCnt++
            #否则,递归处理下一个目录
            else    
              if [[ "$1" != */ ]];then
                recursive $1/${arr[3]}
              else
                recursive $1${arr[3]}
              fi
            fi
          elif [[ "${arr[0]:0:1}" == "-"  ]];then
            #echo "    $1/${arr[3]}"
            #如果文件存在天数大于60天,则删除(该条规则目前作废)
            #if [ $diffDays -gt 60 ];then
            #  echo "    $1/${arr[3]}:该文件存在时间超过60天,删除之"
            #  rm -f $1/${arr[3]}
            #  let fileCnt++
    
            #文件创建/修改日期距离当前日期的天数
            diffDays=$((($(date +%s) - $(date +%s -d ${arr[2]}))/86400))
            #如果文件大于100M(104857600字节),且存在时间超过5天,则删除
            if [[ ${arr[1]} -gt 104857600 && $diffDays -gt 5 ]];then
              rm -f $1/${arr[3]}
              echo "    $1/${arr[3]}:该文件大于100M,且存在时间超过5天,删除之"
              echo "    $1/${arr[3]}:该文件大于100M,且存在时间超过5天,删除之" >> $logPath
              let fileCnt++
            fi
          fi
        done <<< "`ls -l --time-style='+%Y%m%d' $1 | awk '{print $1,$5,$6,$7}'`"
      #fi
    }
    
    if [[ "$1" == "" ]];then
      echo -e "请输入一个参数,指定要清理的目录!
    "
      echo -e "请输入一个参数,指定要清理的目录!
    " >> $logPath
      exit 1
    else
      recursive $1
    fi
    
    if [[ $dirCnt -eq 0 && $fileCnt -eq 0 ]];then
      echo -e "
    $(date +%Y%m%d" "%H:%M:%S): 清理程序执行完毕!没有要删除的文件!
    "
      echo -e "
    $(date +%Y%m%d" "%H:%M:%S): 清理程序执行完毕!没有要删除的文件!
    " >> $logPath
    else
      echo -e "
    $(date +%Y%m%d" "%H:%M:%S): 清理程序执行完毕!共删除了 ${dirCnt} 个目录,和 ${fileCnt} 个文件!
    "
      echo -e "
    $(date +%Y%m%d" "%H:%M:%S): 清理程序执行完毕!共删除了 ${dirCnt} 个目录,和 ${fileCnt} 个文件!
    " >> $logPath
    fi
    exit 
    

    方法二

    #还未全部测试
    #删除大于100M,且超过5天的文件
    find . -size +100M -mtime +5 -type f -exec ls -alh {}  >> yx.log;
    find . -size +100M -mtime +5 -type f -exec rm -rf {} ;
    
    #删除超过30天的文件夹
    find /data -mindepth 2 -maxdepth 2 -type d -mtime +30 -exec ls -ahl15 {} ;
    find /data -mindepth 2 -maxdepth 2 -type d -mtime +30 -exec rm -rf {} ;
    

    一、过程中涉及的知识:

    1、

    查看当前目录的总大小

    sudo du -sh .

    查看当前目录下的所有子目录和子文件的总大小

    sudo du -sh *

    查看指定目录的总大小

    sudo du -sh data/

    2、普通的shell脚本使用以下语句作为第一行:

    /bin/bash

    3、修改文件/文件夹的修改时间:
    touch -mt 1901020905 file1

    4、ls 查看格式化后的时间:
    ll --time-style='+%Y%m%d %H:%M:%S'
    -rw-r----- 1 weblogic weblogic 5557932 20190102 09:05:00 aaa.txt

    5、日期的格式化:

    • 特定日期转化为时间戳,即距离1970.01.01 08:00的秒数:
      $(date +%s -d '20120101') #结果为:1325347200
    • 当天和指定日期之间相隔的天数:
      diffDays=$((($(date +%s) - $(date +%s -d '20120101'))/86400))
    • 格式化当前日期:
      echo $(date +%Y%m%d" "%H:%M:%S) #结果是:20191205 13:56:24

    6、单、双括号运算符:
    shell单括号运算符号:
    a=$(date);
    等同于:a=date;
    双括号运算符:
    a=$((1+2));
    echo $a;
    等同于:
    a=expr 1 + 2

    7、awk知识:

    • 在awk中,输入文本的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。awk工作流程是这样的:读入有' '换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,$1表示第一个域,$n表示第n个域。
    • -F ':' 指定输入值的域分隔符(field-separator)为英文冒号 :
      eg. ls -l --time-style='+%Y%m%d' $1 | awk '{print $1,$5,$6,$7}'
      在ls -l列出的文件列表信息中,打印第1、5、6、7个域

    8、echo命令: -e 开启转义
    eg. echo -e "请输入一个参数,指定要清理的目录! "
    注: 表示换行符。

    9、数组:

    • echo ${#arr[@]} #打印数组包含元素的个数
    • echo ${arr[@]} #打印数组的所有元素
    • echo ${arr[0]:0:1} #数组中某个元素从索引0开始截取1个字符,然后打印
    • shell 字符串转换为数组:
      line="a,b,c"
      oldIFS=$IFS
      IFS=, #设置字符串的分隔符为英文逗号,不设置的话默认为空格
      arr=($line)

    10、shell中不能使用别名,如ll等。

    11、vim中全局替换,其中包含了转义符号 :
    :%s//var/log/yx.log/$logPath/g

    二、过程中出现的错误:

    1、Shell脚本报错:
    /usr/local/bin/cleanData.sh: line 32: [: ==: unary operator expected
    原因:在匹配字符串时用了类似这样的语句:
    if[ $timeofday = "yes" ] ...
    如果变量timeofday的值为空,那么就if语句就变成了if [ = "yes" ],这不是一个合法的条件。为了避免出现这种情况,我们必须给变量加上引号if [ "$timeofdat" = "yes" ],这样即使是空变量也提供了合法的测试条件,if [ " " = "yes" ]

    2、Shell脚本报错:
    cleanData.sh: line 63: [: missing `]'
    其中,63行代码为:if [ ${arr[1]} -gt 104857600 && $diffDays -gt 7 ];then
    原因:if使用了单个括号,需要使用双括号。
    小结:网上还有一个错误原因是if ["$NGINX_FLAG" = '1'],"$NGINX_FLAG"之前和'1'之后没有空格,两个都要有空格。
    另外,字符串的if语句比较最好使用双括号。他支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。

  • 相关阅读:
    A physically based scene with three.js
    pbr-guide
    Art Pipeline for glTF
    GG5D
    Leetcode 146.LRU缓存机制
    Leetcode 143.重排链表
    Leetcode 142.环形链表II
    Leetcode 141.环形链表
    Leetcode 139.单词拆分
    Leetcode 138.复制带随机指针的链表
  • 原文地址:https://www.cnblogs.com/mediocreWorld/p/15185909.html
Copyright © 2020-2023  润新知