bash脚本查找文件名中的基于日期的旧文件

问题描述:

我正在开发一个bash脚本,它需要根据一个变量指定需要通过多少天才能在一个单独的“旧”目录中搜索文件超过阈值并且文件被标记为操作(可以是从移动到存档以进行删除等任何操作)。bash脚本查找文件名中的基于日期的旧文件

问题在于,在确定文件在采取动作之前需要多大的文件时,文件的修改时间无关紧要,因为文件很少发生更改,脚本的执行时间可能会有所不同,等等。

决定保存文件的时间是以YYYY-MM-DD(或带有date命令的%F)形式存在于实际文件名中。取例如文件名内容2011-05-23.txt。在这个目录下可以运行哪些命令来查找超过一定天数的所有文件(我的阈值目前设置为7天,可能会更改)并打印出它们的文件名?

在BSD,所述-j用于防止所设置的日期和-f参数用于设定输入的日期的格式。 :

首先,你需要找到今天的天数日期自1970年1月1日:

today=$(date -j -f "%Y-%m-%d" 1969-12-31 +%s) 

现在,你可以用它来找出时间七天前:

((cutoff = $today - 604800)) 

数字604800是七天内的秒数。

现在,对于目录中的每个文件,都需要找到字符串的日期部分。我不知道更好的方法。 (也许有人知道一些Bash魔法)。

find . -type f | while read fileName 
do 
    fileDate=$(echo $foo | sed 's/.*-\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/') 
    yadda, yadda, yadda #Figure this out later 
done 

一旦我们有文件的日期,我们可以使用日期命令,如果该日期要弄清楚在几秒钟不到(因此比截止日期之前)

today=$(date -j -f "%Y-%m-%d" 1969-12-31 +%s) 
((cutoff = $today - 604800)) 
find . -type f | while read fileName #Or however you get all the file names 
do 
    fileDate=$(echo $foo | sed 's/.*-\([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\).*/\1/') 
    fileDateInSeconds=$(date -j -f "%Y-%m-%d" $fileDate +%s) 
    if [ $fileDateInSeconds -lt $cutoff ] 
    then 
      rm $fileName 
    fi 
done 

在Linux中,您使用-d参数来定义必须是在YYYY-MM-DD格式的日期:

today=$(date +"%Y-%m-%d) 

现在,您可以采取的,找到的秒数:

todayInSeconds=(date -d $today +%s) 

其他一切应该或多或少与上述相同。

如果你每天运行的命令,你可以这样做:

echo *-`date -d '8 days ago' '+%F'`.txt 

附加通配符可以ofcourse

加入创建一个bash脚本isOld.sh这样的:

#!/bin/bash 

fileName=$1 
numDays=$2 

fileDt=$(echo $fileName | sed 's/^[^-]*-\([^.]*\)\..*$/\1/') 
d1=$(date '+%s') 
d2=$(date -d $fileDt '+%s') 
diff=$((d1-d2)) 
seconds=$((numDays * 24 * 60 * 60)) 
[[ diff -ge seconds ]] && echo $fileName 

然后通过运行给予上述文件的执行许可:

chmod +x ./isOld.sh 

最后运行这从目录的顶部找到命令打印文件超过7天为:

find . -name "contents-*" -exec ./isOld.sh {} 7 \; 
+0

+1难以击败 – leonbloy 2011-05-23 17:52:42

find *[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]*.txt -exec bash -c 'dt=`echo $0 | sed -re "s/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\1/"`; file_time=`date -d $dt +%s`; cutoff_time=`date -d "31 days ago" +%s` ; test $file_time -lt $cutoff_time ' {} \; -print 

这是我最长的一个衬垫之一:-)这再次包装:

find *[0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]*.txt \ 
    -exec bash -c ' dt=`echo $0 | \ 
        sed -re "s/.*([0-9]{4}-[0-9]{2}-[0-9]{2}).*/\1/"`; \ 
        file_time=`date -d $dt +%s`; \ 
        cutoff_time=`date -d "31 days ago" +%s` ;\ 
        test $file_time -lt $cutoff_time \ 
       ' {} \; -print