这是我的问题,
我有一个文件夹,其中存储了多个具有特定格式的文件:
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模式以匹配它。这样您就可以确保只有符合此模式的文件才会被删除。
答案 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
按照最新版本的修改时间列出文件。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-