使用linux bash脚本清除存档文件

时间:2013-05-24 12:05:18

标签: linux bash scripting

这是我的问题,

我有一个文件夹,其中存储了多个具有特定格式的文件:

Name_of_file.TypeMM-DD-YYYY-HH:MM

其中MM-DD-YYYY-HH:MM是其创建时间。可能有多个文件具有相同的名称但当然不是同一时间。

我想要的是一个可以保留每个文件的3个最新版本的脚本。

所以,我在那里找到了一个例子: Deleting oldest files with shell

但我不想删除一些文件,而是要保留一定数量的新文件。有没有办法获得find命令,解析Name_of_file并保持3最新???

这是我尝试过的代码,但这并不是我需要的。

find /the/folder -type f -name 'Name_of_file.Type*' -mtime +3 -delete

感谢您的帮助!


所以我决定添加我的最终解决方案,以防有人喜欢它。它是给出的两种解决方案的组合。

ls -r | grep -P "(.+)\d{4}-\d{2}-\d{2}-\d{2}:\d{2}" | awk 'NR > 3' | xargs rm

一条线,超级高效。如果日期或名称模式发生任何变化,只需更改grep -P模式以匹配它。这样您就可以确保只有符合此模式的文件才会被删除。

3 个答案:

答案 0 :(得分:1)

假设我们使用文件名中的日期来定义存档文件,并且可以将日期格式更改为YYYY-MM-DD-HH:MM(如上面的注释中所述),这里是一个快速而又脏的shell脚本将每个文件的最新3版本保留在当前工作目录中:

#!/bin/bash
KEEP=3  # number of versions to keep

while read FNAME; do
    NODATE=${FNAME:0:-16}  # get filename without the date (remove last 16 chars)
    if [ "$NODATE" != "$LASTSEEN" ]; then  # new file found
        FOUND=1; LASTSEEN="$NODATE"
    else  # same file, different date
        let FOUND="FOUND + 1"
        if [ $FOUND -gt $KEEP ]; then
            echo "- Deleting older file: $FNAME"
            rm "$FNAME"
        fi
    fi
done < <(\ls -r | grep -P "(.+)\d{4}-\d{2}-\d{2}-\d{2}:\d{2}")

示例运行:

[me@home]$ ls
another_file.txt2011-02-11-08:05  
another_file.txt2012-12-09-23:13  
delete_old.sh
not_an_archive.jpg 
some_file.exe2011-12-12-12:11             
some_file.exe2012-01-11-23:11 
some_file.exe2012-12-10-00:11  
some_file.exe2013-03-01-23:11  
some_file.exe2013-03-01-23:12

[me@home]$ ./delete_old.sh 
- Deleting older file: some_file.exe2012-01-11-23:11
- Deleting older file: some_file.exe2011-12-12-12:11

[me@home]$ ls
another_file.txt2011-02-11-08:05
another_file.txt2012-12-09-23:13
delete_old.sh
not_an_archive.jpg
some_file.exe2012-12-10-00:11
some_file.exe2013-03-01-23:11
some_file.exe2013-03-01-23:12

基本上,但是将文件名更改为表单中的日期为YYYY-MM-DD-HH:MM,正常的字符串排序(例如由ls完成的排序)将自动将按日期时间排序的类似文件组合在一起。

最后一行的ls -r只列出当前工作中的所有文件,直接以相反的顺序打印结果,以便首先显示较新的存档文件。

我们通过grep传递输出,只提取格式正确的文件。

然后循环该命令组合的输出(参见while循环),我们可以在3次出现相同文件名(减去日期部分)后开始删除。

答案 1 :(得分:1)

您是否可以额外确定文件上的时间戳与文件名上的时间戳完全相同?如果他们有点偏离,你关心吗?

ls命令可以按时间戳顺序对文件进行排序。你可以这样做

$ ls -t | awk 'NR > 3' | xargs rm
  • ls -t按照最新版本的修改时间列出文件。
  • `awk'NR&gt; 3'打印出文件列表,除了前三行,这三个是最新的。
  • xargs rm将删除比前三个文件旧的文件。

现在,这不是确切的解决方案。 xargs可能存在问题,因为文件名可能包含奇怪的字符或空格。如果你能保证不是这样的话,这应该没问题。

此外,您可能希望按名称对文件进行分组,并保留最后三个。嗯...

ls | sed 's/MM-DD-YYYY-HH:MM*$//' | sort -u | while read file
do
    ls -t $file* | awk 'NR > 3' | xargs rm
done

ls将列出目录中的所有文件。 sed 's/\MM-DD-YYYY-HH:MM//' will remove the date time stamp from the files. The排序-u`将确保您只有唯一的文件名。因此

file1.txt-01-12-1950
file2.txt-02-12-1978
file2.txt-03-12-1991

将简化为:

file1.txt
file2.txt

这些是通过循环放置的,ls $file*将列出以文件名和后缀开头的所有文件,但会将其传递给awk,这将删除最新的三个,并管道到xargs rm将删除除最新三个之外的所有内容。

答案 2 :(得分:1)

此管道将为您提供当前目录中的3个最新文件(按修改时间)

stat -c $'%Y\t%n' file* | sort -n | tail -3 | cut -f 2-

要获得所有最新的3个:

stat -c $'%Y\t%n' file* | sort -rn | tail -n +4 | cut -f 2-