一、需求背景
由于业务需要,在特定的FTP下会不断的产生相关文件,大概每分钟一个文件,每天1500个上下。但是长期下去单个目录下文件数量就会太多,可能导致性能问题。所以现在想按照日期将文件分类,将同一天产生的文件放到以产生文件日期命名的目录下,比如所有在2017-01-01产生的文件都放在20170101目录下。
二、技术思路
可以定时遍历目标文件所在源目录,利用stat获取单个文件的时间信息,然后将其mv到以其时间信息为特征命名的目的目录中去。
1、定时执行脚本可利用Linux的cron。使用crontab -e来编辑其配置文件。
crontab配置格式如下:
f1 f2 f3 f4 f5 program
其中f1是表示分钟,f2表示小时,f3表示一个月份中的第几日,f4表示月份,f5表示一个星期中的第几天。program 表示要执行的程序。当f1为*时表示每分钟都要执行program,f2为*时表示每小时都要执行程序,其馀类推。
当 f1 为*时表示每分钟都要执行 program,f2为*时表示每小时都要执行程序,其馀类推。
当f1为a-b时表示从第a分钟到第b分钟这段时间内要执行,f2为a-b时表示从第a到第b小时都要执行,其馀类推。
当f1为*/n时表示每n分钟个时间间隔执行一次,f2为*/n表示每n小时个时间间隔执行一次,其馀类推。
当f1为 a, b, c,... 时表示第 a, b, c,...分钟要执行,f2 为a, b, c,... 时表示第 a, b, c...个小时要执行,其馀类推。
若想要脚本每分钟执行一次:
* * * * * script.sh
2、在Linux中,没有文件创建时间的概念。只有文件的访问时间、修改时间、状态改变时间。也就是说不能知道文件的创建时间。但如果文件创建后就没有修改过,修改时间=创建时间;如果文件创建后,状态就没有改变过,那么状态改变时间=创建时间;如果文件创建后,没有被读取过,那么访问时间=创建时间,这个基本不太可能。
由于源文件产生之后并不会被修改,故采用文件修改时间作为其产生时间。如下例中的Modify一行。
[liuhao@my test]$ stat sh.sh
File: "sh.sh"
Size: 524 Blocks: 8 IO Block: 4096 普通文件
Device: fd02h/64770d Inode: 168698107 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 509/ liuhao) Gid: ( 0/ root)
Access: 2017-01-23 09:51:32.160824300 +0800
Modify: 2017-01-23 09:51:29.293824304 +0800
Change: 2017-01-23 09:51:29.294824304 +0800
3、利用awk处理stat得到的文件产生时间信息来得到目标文件目录名。
date=`stat $file | grep "Modify:" | awk -F ":| |-" '{print $3$4$5}'`
if [ ! -e $date ];then
mkdir $date
fi
三、代码实现
#! /bin/sh
rootDir="/home/liuhao/test/"
sDir=$rootDir
echo $sDir
cd $rootDir"/test"
touch ./.date
#Modify: 2017-01-23 09:31:37.228825682 +0800
dDir=`stat ./.date | grep "Modify:" | awk -F ":| |-" '{print $3$4$5}'`
echo $dDir
#现在看来,和dDir相关的都没用了
if [ ! -e $dDir ];then
mkdir $dDir
fi
for file in $rootDir/*
do
if [ -f $file ];then
date=`stat $file | grep "Modify:" | awk -F ":| |-" '{print $3$4$5}'`
if [ ! -e $date ];then
mkdir $date
fi
echo $file $date
mv $file $date
fi
done