我想创建一个 shell 脚本来删除除最后 n 个文件之外的旧版本文件。换句话说,当我部署新版本时,仅保留最后 n 个版本。
文件名具有以下格式:
appname_releasenumber_date.tar.gz
也许有一个简单的解决方案可以做到这一点,但我不知道如何做到这一点。
我找到了这个解决方案在 Linux 上删除包含日期戳作为文件名一部分的文件的更简洁方法但我需要先生成一些文件,以保留我想要的文件数量。
答案1
我将更改@Salton 的答案,使其更通用:
ls -1 | sort -t_ -n -k2 | head -$((`ls | wc -l`-1)) | xargs rm -rf
这个按版本号排序并完全忽略日期。因此,如果旧版本有较新的日期,则旧版本将被删除。
答案2
在 zsh 中,如果您的版本按字典顺序排列:
rm -f appname_*.tar.gz(N[1,-$((n+1))])
这全局限定符 [NUM1,NUM2]
仅保留从 NUM1 到 NUM2 的匹配项。使用减号时,数字从末尾开始计数(-1 是最后一个匹配项),因此[1,-$((n+1))]
匹配除最后一个$n
文件之外的所有文件。 glob 限定符N
表示如果没有匹配项也没关系(如果$n
已经存在的文件数不多的话就会发生这种情况)。
如果版本不按字典顺序排列,您可能需要按不同的顺序对文件进行排序。 glob 限定符n
按值对十进制数字进行排序,因此如果您appname_9_somedate
后面跟有appname_10_someotherdate
.
rm -f appname_*.tar.gz(nN[1,-$((n+1))])
如果您有更复杂的版本号,您可以指定自己的排序函数。编写一个 zsh 函数,version_less
如果第一个参数小于第二个参数,则返回 0,并使用
rm -f appname_*.tar.gz(N[1,-$((n+1))]o+version_less)
在任何 shell 中,如果文件的顺序是字典顺序,则可以迭代匹配项。
set appname_*.tar.gz
while [ $# -gt $n ]; do
rm "$1"
shift
done
如果您需要不同的顺序,解析 的输出ls
是您最好的选择。请注意,这ls
会破坏文件名中的不可打印字符,但在您的情况下,这应该不是问题。
答案3
您可以搜索最旧的文件,然后检查文件总数是否大于 N 个文件,然后首先在脚本中删除最旧的文件,或者您也可以简单地使用以下示例。假设您不想删除最后 3 个最新文件:
ls -t1 | tail -n +4 | xargs rm -rf