linux shell 脚本 历史文件清理脚本,按天,按月,清理前N天的历史文件,删除指定大小历史文件,历史文件归档清理
不知道大家那有没有要清理的这个事情。需要清理目录历史文件。可能后续也会有很多其他地方需要清理历史文件,可能会用到。
我这两天空闲写了个脚本,清理比较方便,有要进行清理的大量历史文件的话可以用。
脚本用到的命令只有linux才有,像solaris等就不支持,所以只能在linux上运行。如果是nas存储的话,可以挂载到一个linux主机上跑脚本清理。
另外,脚本查找文件用的是ls,但是ls也有最大文件的限度(大概10w以内),如果每天文件很多,每天都是10w+的,运行可能提示文件数过多无法ls。
还有,脚本内有个默认的限制,就是清理的文件的创建日期是跟文件名上的时间是相同的,如果是不同的话,是不会清理的,这是为了避免清理错了。
我写了两个版本的清理脚本,一个是直接清理文件的clearfile.sh,一个是把文件按天/月进行归档(归档成文件夹或压缩包形式)clearfile_ar.sh:
(一)单纯清理文件使用clearfile.sh
文件名是带有时间戳的文件,类似如下(或其他时间格式,后面描述)
按天/月清理:修改脚本内的CLEAR_TYPE参数,D是天,M是月
如果是按月的话,脚本按你输入的月份进行整月清理,不会看你输入的天的时间
清理指定期间内所有文件:
./clearfile.sh/wls/investop/tmp/ 20170515 20170516
清理指定期间内固定大小文件(ls -l显示的大小):
./clearfile.sh /wls/investop/tmp/ 20170515 20170516 40
其他文件日期格式清理:
脚本默认(TRUNC_DATE_FLAG参数为N)是清理上面截图这类格式的,没有任何间隔符的文件名。
如果文件名是有其他间隔符的,如*2017_05_16*这种的。
首先需要调整下脚本里的trunc()方法,把标黄的年月日之间的分隔符改成需要的分隔符(按天和按月两种哦)
然后再设置TRUNC_DATE_FLAG参数为Y,来让脚本使用你指定的日期格式清理
(二)归档方式清理历史文件,使用clearfile_ar.sh
使用方式与clearfile.sh相同,唯一不同的是要设置脚本里的DEL_FLAG参数。
按天/月清理同clearfile.sh
清理指定期间内所有文件同clearfile.sh
清理指定期间内固定大小文件 同clearfile.sh
其他文件日期格式清理 同clearfile.sh
模式1:DEL_FLAG=N
脚本只会把文件按天/按月归档到以时间命名的文件夹内,如
模式2:DEL_FLAG=Y
把文件归档成压缩文件*tar.gz,并删除归档的文件夹
PS,对于大量需要清理的目录,可以写一个非常简单的脚本来批量执行,类似
但是要去掉脚本里的是否确认执行这个反馈,否则脚本执行还是要你输入Y。
~~~~~~~~~~~~~~~~~~脚本如下~~~~~~~~~~~~~~~~~~
clearfile.sh
#!/bin/bash
################################
##参数设置
################################
TODAY=`date +%Y%m%d`
DATE_BEGIN=`date +%Y%m%d`
DATE_END=`date +%Y%m%d`
DATE_FORMATION="%Y%m%d"
FILESIZE=""
COUNTING=0
#需要手工设置,按月清理不会根据输入日期的天清理,只能清理整个月。
CLEAR_TYPE=M
#需要手工设置,是否需要转换日期格式,需要的话,要根据格式设置trunc()方法
TRUNC_DATE_FLAG=N
if [ -f count.tmp ]
then
echo "" > count.tmp
fi
################################
##日期格式转换,eg:trunc 20170512
################################
trunc()
{
if [ "D" = "$CLEAR_TYPE" ]
then
OPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})(.{2})$/\1_\2_\3/g'`
else
OPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})$/\1_\2/g'`
fi
}
################################
##按日清理递归
################################
dayclear()
{
echo "================================"
echo "day clear working on $DATE_END"
doclear $DATE_END
priday $DATE_END
if [ $DATE_END -lt $DATE_BEGIN ]
then
echo "================================"
echo "Total cleard : $COUNTING "
echo "dayclear end"
return
fi
dayclear
}
################################
##按月清理递归
################################
monthclear()
{
echo "================================"
echo "clearfun working on $DATE_END"
doclear $DATE_END
primonth $DATE_END
if [ $DATE_END -lt $DATE_BEGIN ]
then
echo "================================"
echo "Total cleard : $COUNTING "
echo "monthclear end"
return
fi
monthclear
}
################################
##前一日日期,eg:priday 20170421
################################
priday()
{
SEC=`date -d $1 +%s`
PRI_SEC=$[${SEC}-86400]
PRI_DAY=`date -d @${PRI_SEC} +%Y%m%d`
DATE_END=$PRI_DAY
}
################################
##前一月日期,eg:primonth 201704
################################
primonth()
{
#TMP_D=`echo $1 | cut -c 1-6`
#TMP_D=${TMP_D}"01"
TMP_D=`echo $1`"01"
SEC=`date -d $TMP_D +%s`
PRI_SEC=$[${SEC}-86400]
PRI_MON=`date -d @${PRI_SEC} +%Y%m`
DATE_END=$PRI_MON
}
################################
##清理文件
################################
doclear()
{
#默认的日期格式,如20170512,201705
THE_DATE=$1
OPR_DATE=$1
#转换OPR_DATE的日期格式,如2017-05-12,2017-05
if [ "Y" = ${TRUNC_DATE_FLAG} ] ; then
trunc $1
fi
echo "clearing"
if [ "" == "${FILESIZE}" ]
then
#ROW=`ls -l *${OPR_DATE}* | awk '{ print $9;output="ls -l "$9;system(output);}' | wc -l`
ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | grep -v archive | awk -v date_str=${THE_DATE} 'BEGIN{count=0}{if (date_str==$6) {count+=1;output="rm "$7;system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'
ROW=`cat count.tmp`
COUNTING=$[ $COUNTING + $ROW ]
else
#ROW=`ls -l *${OPR_DATE}* | awk -v the_size=${FILESIZE} '{if ($5==the_size) {output="ls -l "$9;system(output)}}' | wc -l`
ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | awk -v the_size=${FILESIZE} -v date_str=${THE_DATE} 'BEGIN{count=0}{if (the_size==$5 && date_str==$6) {count+=1;output="rm "$7;system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'
ROW=`cat count.tmp`
COUNTING=$[ $COUNTING + $ROW ]
fi
echo "clear $THE_DATE finished, clear file $ROW "
}
#######################################
## main function
## 判断参数是否正确,可以输入如下:
## 清理所有文件:clear 20150601 20161231
## 清理固定大小字节文件:clear 20150601 20161231 40
## 清理固定大小字节文件:clear 20150601 20161231 40
#######################################
#清理所有文件,
if [ $# -ne 3 ] && [ $# -ne 4 ]
then
echo "请输入正确的参数"
echo "如清理/nfsc/hipo/bak目录下,从2015年4月1号到2016年12月31号的所有文件(默认按日清理):clearfile /nfsc/hipo/bak 20150401 20161231"
echo "或清理清理/nfsc/hipo/bak目录下,从2015年4月1号到2016年12月31号的大小为40字节的文件(默认按日清理):clearfile /nfsc/hipo/bak 20150401 20161231 40"
exit 1
else
DATE_BEGIN=$2
DATE_END=$3
FILESIZE=$4
date -d $2 2>&-
ERR1=$?
date -d $3 2>&-
ERR2=$?
if [ $ERR1 -eq 1 ] || [ $ERR2 -eq 1 ]; then
echo "date formation error, input the correct date string like 20170131."
exit 1
elif [ $DATE_BEGIN -gt $DATE_END ]; then
echo "BEGIN DATE is later than END DATE, please correct."
exit 1
elif [ $TODAY -lt $DATE_END ]; then
echo "END DATE is later than NOW DATE, please correct"
elif [ ! -d $1 ]; then
echo "DIR $1 does not exist."
exit 0
fi
fi
cd $1
THEDIR=`pwd`
echo ">>>>clear the DIR $THEDIR "
echo ">>>>clear file between $DATE_BEGIN and $DATE_END."
if [ "" == "${FILESIZE}" ]; then
echo ">>>>every size of the files will be clear"
else
echo ">>>>clear filesize only is ${FILESIZE}"
fi
if [ "D" == "${CLEAR_TYPE}" ]; then
echo ">>>>clear set by DAY"
else
echo ">>>>clear by MONTH"
fi
read -p "please confirm the information above,enter Y to continue, other to exit : " ANWSER
#确认继续
if [ ! -n "$ANWSER" ] || [ $ANWSER != Y ]
then
echo "exit"
exit 0
fi
echo "[`date +%Y%m%d-%H%M%S`]==START=="
if [ "D" = "$CLEAR_TYPE" ]
then
echo "DAY clear begin "
DATE_FORMATION="%Y%m%d"
dayclear
else
echo "MONTH clear begin "
DATE_BEGIN=`echo $2 | cut -c 1-6`
DATE_END=`echo $3 | cut -c 1-6`
DATE_FORMATION="%Y%m"
monthclear
fi
echo "[`date +%Y%m%d-%H%M%S`]==END=="
clearfile_ar.sh
#!/bin/bash
################################
##参数设置
################################
TODAY=`date +%Y%m%d`
DATE_BEGIN=`date +%Y%m%d`
DATE_END=`date +%Y%m%d`
DATE_FORMATION="%Y%m%d"
FILESIZE=""
COUNTING=0
#需要手工设置,按月清理不会根据输入日期的天清理,只能清理整个月。
CLEAR_TYPE=M
#需要手工设置,是否删除归档的文件,只保留压缩文件
DEL_FLAG=N
#需要手工设置,是否需要转换日期格式,需要的话,要根据格式设置trunc()方法
TRUNC_DATE_FLAG=N
if [ -f count.tmp ]
then
echo "" > count.tmp
fi
################################
##日期格式转换,eg:trunc 20170512
################################
trunc()
{
if [ "D" = "$CLEAR_TYPE" ]
then
OPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})(.{2})$/\1_\2_\3/g'`
else
OPR_DATE=`echo $1 | sed -r 's/^(.{4})(.{2})$/\1_\2/g'`
fi
}
################################
##按日清理递归
################################
dayclear()
{
echo "================================"
echo "day clear working on $DATE_END"
doclear $DATE_END
priday $DATE_END
if [ $DATE_END -lt $DATE_BEGIN ]
then
echo "================================"
echo "Total cleard : $COUNTING "
echo "dayclear end"
return
fi
dayclear
}
################################
##按月清理递归
################################
monthclear()
{
echo "================================"
echo "clearfun working on $DATE_END"
doclear $DATE_END
primonth $DATE_END
if [ $DATE_END -lt $DATE_BEGIN ]
then
echo "================================"
echo "Total cleard : $COUNTING "
echo "monthclear end"
return
fi
monthclear
}
################################
##前一日日期,eg:priday 20170421
################################
priday()
{
SEC=`date -d $1 +%s`
PRI_SEC=$[${SEC}-86400]
PRI_DAY=`date -d @${PRI_SEC} +%Y%m%d`
DATE_END=$PRI_DAY
}
################################
##前一月日期,eg:primonth 201704
################################
primonth()
{
#TMP_D=`echo $1 | cut -c 1-6`
#TMP_D=${TMP_D}"01"
TMP_D=`echo $1`"01"
SEC=`date -d $TMP_D +%s`
PRI_SEC=$[${SEC}-86400]
PRI_MON=`date -d @${PRI_SEC} +%Y%m`
DATE_END=$PRI_MON
}
################################
##清理文件
################################
doclear()
{
#默认的日期格式,如20170512,201705
THE_DATE=$1
OPR_DATE=$1
#转换OPR_DATE的日期格式,如2017-05-12,2017-05
if [ "Y" = ${TRUNC_DATE_FLAG} ] ; then
trunc $1
fi
#创建归档文件夹
echo "clearing"
if [ ! -d ${THE_DATE}"archive" ] ;then
mkdir "${THE_DATE}"archive
ERR=$?
if [ 0 != ${ERR} ]; then
echo "failed to create archive dir under "`pwd`
exit 0
fi
echo "created the archive directory ${THE_DATE}archive"
chmod 777 ${THE_DATE}"archive"
else
echo "the archive directory already exist ${THE_DATE}archive"
fi
#如果要删除历史的归档文件,判断是否已经存在过历史文件的压缩包
if [ -f "${THE_DATE}archive.tar.gz" ] && [ "Y" = "${DEL_FLAG}" ] ;then
echo "file ${THE_DATE}archive.tar.gz already exits, and again you choose to archive the file which had been archived ,this will cause the old tar.gz file tobe overwirted."
echo "you should confirm the date parameter you input, or you can mv the exits *.tar.gz file to other directory."
exit 0
fi
if [ "" == "${FILESIZE}" ]
then
ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | grep -v archive | awk -v date_str=${THE_DATE} 'BEGIN{count=0;}{if (date_str==$6) {count+=1;output="mv "$7" "date_str"archive/";system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'
if [ "Y" = "${DEL_FLAG}" ] ; then
tar -cf - ${THE_DATE}"archive/" | gzip > ${THE_DATE}"archive.tar.gz"
rm -rf ${THE_DATE}"archive/"
fi
ROW=`cat count.tmp`
COUNTING=$[ $COUNTING + $ROW ]
else
ls -ld --time-style +${DATE_FORMATION} *${OPR_DATE}* | grep -v archive | awk -v the_size=${FILESIZE} -v date_str=${THE_DATE} 'BEGIN{count=0;}{if (the_size==$5 && date_str==$6) {count+=1;output="mv "$7" "date_str"archive/";system(output);}}END{oo="echo "count" > count.tmp";system(oo);}'
if [ "Y" = "${DEL_FLAG}" ] ; then
tar -cf - ${THE_DATE}"archive/" | gzip > ${THE_DATE}"archive.tar.gz"
rm -rf ${THE_DATE}"archive/"
fi
ROW=`cat count.tmp`
COUNTING=$[ $COUNTING + $ROW ]
fi
echo "clear $THE_DATE finished, clear file $ROW "
}
#######################################
## main function
## 判断参数是否正确,可以输入如下:
## 清理所有文件:clear 20150601 20161231
## 清理固定大小字节文件:clear 20150601 20161231 40
## 清理固定大小字节文件:clear 20150601 20161231 40
#######################################
#清理所有文件,
if [ $# -ne 3 ] && [ $# -ne 4 ]
then
echo "请输入正确的参数"
echo "如清理/nfsc/hipo/bak目录下,从2015年4月1号到2016年12月31号的所有文件(默认按日清理):clearfile /nfsc/hipo/bak 20150401 20161231"
echo "或清理清理/nfsc/hipo/bak目录下,从2015年4月1号到2016年12月31号的大小为40字节的文件(默认按日清理):clearfile /nfsc/hipo/bak 20150401 20161231 40"
exit 1
else
DATE_BEGIN=$2
DATE_END=$3
FILESIZE=$4
date -d $2 2>&-
ERR1=$?
date -d $3 2>&-
ERR2=$?
if [ $ERR1 -eq 1 ] || [ $ERR2 -eq 1 ]; then
echo "date formation error, input the correct date string like 20170131."
exit 1
elif [ $DATE_BEGIN -gt $DATE_END ]; then
echo "BEGIN DATE is later than END DATE, please correct."
exit 1
elif [ $TODAY -lt $DATE_END ]; then
echo "END DATE is later than NOW DATE, please correct"
elif [ ! -d $1 ]; then
echo "DIR $1 does not exist."
exit 0
fi
fi
cd $1
THEDIR=`pwd`
echo ">>>>clear the DIR $THEDIR "
echo ">>>>clear file between $DATE_BEGIN and $DATE_END."
if [ "" == "${FILESIZE}" ]; then
echo ">>>>every size of the files will be clear"
else
echo ">>>>clear filesize only is ${FILESIZE}"
fi
if [ "D" == "${CLEAR_TYPE}" ]; then
echo ">>>>clear set by DAY"
else
echo ">>>>clear by MONTH"
fi
read -p "please confirm the information above,enter Y to continue, other to exit : " ANWSER
#确认继续
if [ ! -n "$ANWSER" ] || [ $ANWSER != Y ]
then
echo "exit"
exit 0
fi
echo "[`date +%Y%m%d-%H%M%S`]==START=="
if [ "D" = "$CLEAR_TYPE" ]
then
echo "DAY clear begin "
DATE_FORMATION="%Y%m%d"
dayclear
else
echo "MONTH clear begin "
DATE_BEGIN=`echo $2 | cut -c 1-6`
DATE_END=`echo $3 | cut -c 1-6`
DATE_FORMATION="%Y%m"
monthclear
fi
echo "[`date +%Y%m%d-%H%M%S`]==END=="
---------------------
作者:oicp110
来源:CSDN
原文:https://blog.csdn.net/oicp110/article/details/71214201
版权声明:本文为博主原创文章,转载请附上博文链接!
linux shell 脚本 历史文件清理脚本,按天,按月,清理前N天的历史文件,删除指定大小历史文件,历史文件归档清理的更多相关文章
- Linux下删除空文件,删除指定大小的文件
Linux下批量删除空文件(大小等于0的文件)的方法: find . -name "*" -type f -size 0c | xargs -n 1 rm -f 用这个还可以删除指 ...
- [No000073]C#直接删除指定目录下的所有文件及文件夹(保留目录)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C# 删除指定目录下的所有文件及文件夹
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- C#直接删除指定目录下的所有文件及文件夹(保留目录)
#region 直接删除指定目录下的所有文件及文件夹(保留目录) /// <summary> /// 直接删除指定目录下的所有文件及文件夹(保留目录) /// </summary&g ...
- powershell编程实例-001-生成指定大小的null/zero文件或随机文件
NULL文件,也有的称为zero文件,即全是二进制/十六进制的0文件 在powershell 中可以按如下方法生成指定大小的zero文件: 只需要修改大小即可,格式如3MB,或者2GB $tempFi ...
- 数据仓库005 - 复习Linux shell命令 - crontab调度 sh脚本 后台执行 软连接
一.crontab调度 对于linux 自带crontab而言, xxx.sh的一般编写格式以#!/bin/bash 解释器开头,可在脚本中加入: date 但是,shell脚本执行 需要 ...
- [转]linux shell 获取当前正在执行脚本的绝对路径
原文链接:http://sexywp.com/bash-how-to-get-the-basepath-of-current-running-script.htm 常见的一种误区,是使用 pwd 命令 ...
- linux shell:nginx日志切割脚本
需求原因:nginx不具备日志切割功能,日志量较大,方便分析. 实现目的:完成nginx日志切割,并根据时间命名 简要命令: mv /usr/local/tengine/logs/access.l ...
- Linux下如何遍历指定目录下的所有文件并删除指定天数之前创建的文件
脚本内容如下: #!/bin/bash function delete_file { days=$[$-] for i in `find $dir -type f -ctime +$days` do ...
随机推荐
- ACM学习历程—HDU 5446 Unknown Treasure(数论)(2015长春网赛1010题)
Problem Description On the way to the next secret treasure hiding place, the mathematician discovere ...
- python实现redis三种cas事务操作
cas全称是compare and set,是一种典型的事务操作. 简单的说,事务就是为了存取数据库中同一数据时不破坏操作的隔离性和原子性,从而保证数据的一致性. 一般数据库,比如MySql是如何保证 ...
- Marionettejs
Marionette是牵线木偶的意思,这个库是对Backbone的一次更高层次封装.这样的封装有两个目标: 减少重复的工作,提高使用Backbonejs时的生产效率给复杂应用页面提供更多的结构,以支撑 ...
- 51nod 1301 集合异或和——异或dp
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1301 好题!看了TJ才会. 因为是不可重集合,所以当然有前 i 个 ...
- 不同类型input尺寸设置区别
最近发现为不用类型的input设置相同的尺寸,却得到了不一样的尺寸结果.发现不同类型的input的height和width竟然含义不同.在此小整理一下. (1)button类型 规律 button类型 ...
- java代码throws异常
总结:抛出异常 package com.ds; //异常捕获 public class fdsg { private static void throwException() { try { Stri ...
- Spark Streaming之六:Transformations 普通的转换操作
与RDD类似,DStream也提供了自己的一系列操作方法,这些操作可以分成四类: Transformations 普通的转换操作 Window Operations 窗口转换操作 Join Opera ...
- TModJS:目录
ylbtech-TModJS:目录 1.返回顶部 1. https://github.com/aui/tmodjs 2. https://www.npmjs.com/package/tmodjs 3. ...
- 使用ceph命令提示handle_connect_reply connect got BADAUTHORIZER
输入命令提示如下错误: [root@node1 ~]# rados -p testpool ls 2017-10-21 06:13:25.743045 7f8f89b6d700 0 -- 192.16 ...
- c语言基础 c和指针
句子 c规定数组名代表数组首元素的地址 如果&a 则代表整个数组 没有内存哪来的指针 数据类型的本质:固定大小内存的别名 变量的本质:(一段连续)内存空间的别名,内存空间的标号 指针是一种数据 ...