3

I want to create a shell script that deletes old release files except last n files. In other words, only mantain last n releases when I deploy a new release.

File names have this format:

appname_releasenumber_date.tar.gz

Maybe there's an easy soluction to do this, but I cannot figure out how to do this.

I've found this solution Cleaner way to delete files on Linux which include a datestamp as part of file name but I need to generate some files first in order to keep the number of files I want to.

4
  • What's the format for the date component in the file names?
    – iruvar
    Commented Jun 19, 2013 at 14:55
  • Are all the files for the same appname in the directory or can they be with different appname?
    – unxnut
    Commented Jun 19, 2013 at 15:52
  • -2012-06-11_14-57-37.tar.gz -> year-month-day_hours-minutes-seconds.tar.gz
    – Feida Kila
    Commented Jun 19, 2013 at 15:52
  • appname is always the same, but thanks anyway I got to the correct answer thanks to salton one
    – Feida Kila
    Commented Jun 19, 2013 at 16:00

3 Answers 3

5

I am going to change the answer by @Salton to make it more general:

ls -1 | sort -t_ -n -k2 | head -$((`ls | wc -l`-1)) | xargs rm -rf

This one sorts on version number and ignores the date completely. So, if an older version has a newer date, the older version will be removed.

1
  • quite a pro answer ;)
    – Feida Kila
    Commented Jun 19, 2013 at 16:06
2

In zsh, if your versions are in lexicographic order:

rm -f appname_*.tar.gz(N[1,-$((n+1))])

The glob qualifier [NUM1,NUM2] retains only the matches from NUM1 to NUM2. With a minus sign, the number counts from the end (-1 is the last match), so [1,-$((n+1))] matches all but the last $n files. The glob qualifier N says that it's ok if there is no match (which happens if there are no more than $n files already).

If the versions aren't in lexicographic order, you may need to sort the files in a different order. The glob qualifier n sorts decimal numbers by value, so this will work correctly if you have appname_9_somedate followed by appname_10_someotherdate.

rm -f appname_*.tar.gz(nN[1,-$((n+1))])

If you have more complex version numbers, you can specify your own sort function. Write a zsh function version_less that returns 0 if its first argument is less than its second argument, and use

rm -f appname_*.tar.gz(N[1,-$((n+1))]o+version_less)

In any shell, if the order of the files is lexicographic order, you can iterate through the matches.

set appname_*.tar.gz
while [ $# -gt $n ]; do
  rm "$1"
  shift
done

If you need a different order, parsing the output of ls is your best bet. Note that ls mangles non-printable characters in file names, but in your case that shouldn't be a problem.

1

You can search oldest files and then you can check if total number of files are more then N files then delete oldest files first in a script or you can also simply use the following example. Let's say you don't want to delete last 3 latest files:

ls -t1 | tail -n +4 | xargs rm -rf

3
  • This assumes that the modification times are right—may not be the case depending on how the files got there. (E.g., generated from a version control branch will usually have the date it was generated, or possibly even copied to the server, not the date of the most recent change)
    – derobert
    Commented Jun 19, 2013 at 15:34
  • Yes, I assumed that build script generating this release in a directory and no manual copy is taking place.
    – Raza
    Commented Jun 19, 2013 at 15:40
  • i did an order modification and got to the result, thank you very much
    – Feida Kila
    Commented Jun 19, 2013 at 15:57

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .