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 ...
随机推荐
- JAVA 1.7并发之Fork/Join框架
在之前的博文里有说过executor框架,其实Fork/Join就是继承executor的升级版啦 executor用于创建一个线程池,但是需要手动的添加任务,如果需要将大型任务分治,显然比较麻烦 而 ...
- Makefile经典教程
转自:http://blog.csdn.net/ruglcc/article/details/7814546/ makefile很重要 什么是makefile?或许很多Winodws的程序 ...
- windows7下安装gem包---bcrypt-ruby
在Gemfile中添加 gem 'bcrypt-ruby', '~> 3.0.0' 然后执行bundle install,rails服务启动没有问题,但是运行程序时页面报错如下: cannot ...
- Java泛型通配符以及限定
摘抄笔记 A:泛型的限定 /* * 将的酒店员工,厨师,服务员,经理,分别存储到3个集合中 * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 */ import java.uti ...
- Learning Python 004 基础的数据类型和变量
Python 基础的数据类型和变量 数据类型 整数 Python可以处理任意大小的整数,当然包括负整数. Python表示十六进制也用0x前缀. 浮点数 1.23x10^9和12.3x10^8是完全相 ...
- Java基础——深入剖析Java中的装箱和拆箱
(转自:http://www.cnblogs.com/dolphin0520/p/3780005.html) 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若 ...
- 292C Beautiful IP Addresses
传送门 题目 The problem uses a simplified TCP/IP address model, please read the statement carefully. An I ...
- 5.6 安装SqlDeveloper
首先,将安装包准备好: 打开终端: 这样,sqldeveloper就安装完毕了. 在Ubuntu中搜索,sql,会出现: 点击,可以进入:
- 28.【转载】挖洞技巧:APP手势密码绕过思路总结
说到APP手势密码绕过的问题,大家可能有些从来没接触过,或者接触过,但是思路也就停留在那几个点上,这里我总结了我这1年来白帽子生涯当中所挖掘的关于这方面的思路,有些是网上已经有的,有些是我自己不断摸索 ...
- javascript 操作符小结
简单总结一下JavaScript的几个操作符: var. in. delete. typeof. new. instanceof.void var 定义变量要使用var操作符, 使用var操作符定义的 ...