我有以下任务:删除超过30天的旧“版本”。这个解决方案非常有效:
find $jenkins_jobs -type d -name builds -exec find {} -type d -mtime +30 \; >> $filesToBeDelete
cat $filesToBeDelete | xargs rm -rf
但后来添加了一些条件:仅当我们有超过30个构建并清理最旧的构建时才删除。所以在结果中我们应该保留30个最新的构建并删除其余部分。
此外,我发现我可以在查找中使用if语句:
if [ $(find bla-bla | wc -l) -gt 30 ]; then
...
fi
但是我在闲逛如何删除这些文件。
清楚吗?例如,我们在“build”文件夹中有100个版本,所有这些版本都超过30天。所以我想保留30个新版本并删除另外70个版本。
答案 0 :(得分:2)
非常hacky但对于奇怪的文件名应该非常强大
find -type d -name "builds" -mtime +30 -printf "%T@ %p\0" |\
awk -vRS="\0" -vORS="\0" '{match($0,/([^ ]* )(.*)/,a);b[a[2]]=a[1];c[a[1]]=a[2]}END{x=asort(b);for(i=x-30;i>0;i--)print c[b[i]]}' |\
xargs -0 -I{} rm -r {}
我使用echo测试它似乎工作但我确保它在使用rm -r之前显示正确的文件。
所以它的作用是传递空终止字符串,因此保留了文件名。
主要限制是如果在同一秒内创建了两个文件,那么它会因为使用关联数组而错过一个。
答案 1 :(得分:0)
如果您的stat
足够接近我的(cygwin / bash),这是列出dirs的相对安全答案:
now=$(date +%s)
find $jenkins_jobs -type d -name builds -exec find {} -type d |
while read f; do stat -c'%Y %n' "$f"; done |
sort -nr |
tail -n +31 |
awk $now'-$1>2592000'|
sed 's/^[0-9]* //'
这适用于%s
date
和%Y
stat
提供的纪元时间(自1970年以来的秒数)。 sort
和tail
正在删除最新的30,而awk
正在删除任何30天或更新的版本。 (2592000是30天内的秒数。)最终sed
只是删除了stat
添加的内容,只留下了dirname。
答案 2 :(得分:-2)
这将列出所有,但30个最新的直接下载。
find -type d -name builds -exec ls -d -l --time-style="+%s" {} \;|sed "s#[^ ]\+ \w\+ \w\+ \w\+ \w\+ ##"|sort -r |sed "s#[^ ]\+ ##"|tail -n +31
在确定要删除它们之后,可以使用| xargs rm -rf
它是这样读的: