views:

43

answers:

2

-not sure if this belongs here or on serverfault-

What I want to do it list all directories in a directory and delete all of them, except for the last 5. We have a deployment system in place that will incrementally do something link this:

/var/www/html/build1
/var/www/html/build2
/var/www/html/build3
/var/www/html/build4
/var/www/html/build5
/var/www/html/build6
/var/www/html/build7
/var/www/html/build8
/var/www/html/build9
/var/www/html/build10

This is using up way too much disk space so we only want to keep the last 5 builds.

I came up with the following:

(find /var/www/html/ -type d -name "build*" | sort -r) /var/www/html/build1564 /var/www/html/build1563 /var/www/html/build1560 /var/www/html/build1558 /var/www/html/build1557 /var/www/html/build1556 /var/www/html/build1555 /var/www/html/build1554 /var/www/html/build1553 /var/www/html/build1552 /var/www/html/build1551 /var/www/html/build1550

now all I need to do is add an "offset" to that command, so that the first five directories don't show up. After that, the remaining directories should be removed.

If there are no more than 5 directories, nothing should happen.

I guess I'm still missing two steps here, the offset step and the rm -rf step?

+2  A: 

To get everything but firt 5 use tail -n +5.(I think you don't need to reverse the sort then) and to rm them you can use xargs. So you can try this

find /var/www/html/ -type d -name "build*" | sort | tail -n +5 | xargs -I % echo -rf %

(replace echo with rm to do it)

mb14
thanks, tail +5 gives me: cannot open `+5' for reading: No such file or directory
Jorre
just found out why, it needs tail -n +5
Jorre
the full command gives me "xargs: %": no such file or directory
Jorre
tail +n has been deprecated apparently. Still works on my mac and on old unix
mb14
my mistake, thanks for the quick and perfect response guys!
Jorre
sorry mate, I would love to mark your answer as the right one, but Philipp has a point and a solution that is slightly more efficient in the long run
Jorre
My answer was to the question "how to take the last 5", assuming than you have already sorted everything, as you seemed to know how to do it ;)
mb14
+1  A: 

You can't use sort that way because it doesn't recognize that build10 > build9, for example. You have to cut off the prefix manually:

for dir in build*
do
    echo "${dir#build}"
done | sort -n | head -n -5 | xargs -I '%' echo -r 'build%'

Here is an example that shows where your original code fails:

/tmp $ mkdir build8 build9 build10
/tmp $ find . -type d -name "build*" | sort -r
./build9
./build8
./build10
Philipp
thanks for the tip, is there a way to do this in the command given above?
Jorre
My (corrected) code is very close to mb14's answer, the only difference being the `for` loop and the `-n` option for `sort`. I didn't use `find` because your `build` directories seem to be direct subdirectories of one common parent.
Philipp
the code gives me an incorrent order of build directories to be deleted. it gives (with normal sort) build10001, build50, build60, ... this should be build10001, build60, build50, ...
Jorre
The sorting works correct here; please show an example for the error. However, you have to replace `tail -n +5` by `head -n -5` to delete the oldest instead of the newest directories.
Philipp
for dir in build*; do echo "${dir#build}"; done | sort | xargs -I '%' echo -r 'build%' GIVES -r build10001-r build1558-r build1560-r build1563-r build1564-r build1565
Jorre
the script should list all directories, starting with the latest build nummer, but with an offset of 5 (5 most recent should not be displayed/deleted). All other directories build* must be removed
Jorre
Yes, my code is different, look more carefully at the code and my first comment.
Philipp
aah I see, sort -n should be sort -r, Let me try with that a bit further. Can you update your script above?
Jorre
almost got it, you need to put sort -n -r
Jorre
I think the `-r` is wrong if you use `head`. `head -n -5` gives every line except the last five. Isn't that what you want?
Philipp