3

这是我的问题,

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

Name_of_file.TypeMM-DD-YYYY-HH:MM

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

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

所以,我在那里找到了一个例子: 使用 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 模式以匹配它。这样您就可以确定只有符合此模式的文件才会被删除。

4

3 回答 3

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-
于 2013-05-24T19:14:39.393 回答
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

本质上,但是将文件名更改为日期形式为 to YYYY-MM-DD-HH:MM,普通的字符串排序(例如完成的 by ls)将自动将相似的文件分组在一起,按日期时间排序。

最后ls -r一行简单地列出了当前工作中的所有文件,直接以相反的顺序打印结果,因此较新的存档文件首先出现。

我们传递输出grep以仅提取格式正确的文件。

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

于 2013-05-24T13:20:03.323 回答
1

您能否更加确定文件上的时间戳与文件名上的时间戳完全相同?如果他们有点偏离,你在乎吗?

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

$ ls -t | awk 'NR > 3' | xargs rm
  • 他按修改ls -t时间列出文件,其中最新的在前。
  • `awk 'NR > 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 将列出目录中的所有文件。sort -u`将sed 's/\MM-DD-YYYY-HH:MM//' will remove the date time stamp from the files. The确保您只有唯一的文件名。因此

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

将简化为:

file1.txt
file2.txt

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

于 2013-05-24T13:49:14.233 回答