I noticed today (after ~8 years of happily hacking away at bash) that there is no trivial way to 'delete by date' using ´rm'. The solution is therefore to pipe stuff around a combination of commands like rm, ls, find, awk and sed.
Say for example I wanted to delete every file in the working directory from 2009, what would be a typical stackoverflowers approach?
I came up with the following, which is butt-ugly and should only be run if 'rm' is set to skip over directories (otherwise you will delete the parent directory):
ls -la | awk '{if (substr($6,0,5)==2009) print $8}' | xargs rm
Points for both the most elegant and the most outrageously over-engineered sloutions.
-
I would combine find and rm (without pipe)
find . ...bunch of find criterias to select certain files (e.g. by date) .... -exec rm \{\} \;EDIT: with parameters for your example it would be
find . -maxdepth 1 -type f -ctime -12 -exec rm \{\} \;CAVEAT: This works just today :-). (To make it work everytime, replace the -ctime with absoulte time, see timeXY in the manpage )
OIS : Example here: http://www.howtogeek.com/howto/ubuntu/delete-files-older-than-x-days-on-linux/Rob Kennedy : Is there any danger of "rm" interpreting a file name as a command switch in this scenario, and thus deleting too little or too much?Joachim Sauer : @Rob: Partially: "-exec" calls rm with only one argument each time, so there's only the danger to delete too little. You could replace "rm \{\} \;" with "rm -- \{\} \;" to avoid that.Porges : `\{\}` is superfluous; just use `{}` -
find(1)is a much more efficient to do what you want than parsingls(1)output.EDIT: something to watch for is filenames with spaces in them so you want to have a
findwhich supports-print0(to be used withxargs -0) for better performance.find . -mtime +12 -print0 | xargs -0 rm -f -
Instead of parsing ls(1) which can too easily break you should rely on stat(1):
stat -c '%z/%n' files_or_glob | grep '^date' | cut -d/ -f2- | xargs -d '\n' rm -ie.g.
$ stat -c '%z/%n' *| grep '^2008-12-16' | cut -d/ -f2- | xargs -d '\n' rm -iNote: this will not handle filenames with embedded newlines correctly. However they are rarely found in the wil.d
-
Some versions of find support the -delete option, making it even more efficient...
find . -maxdepth 1 -type f -ctime -12 -delete;Check your find man page (this has worked on most recent releases of Ubuntu for me)
Fergie : nice- I like that there are no pipes or -execsAlastair : Nice, except that it doesn't use rm as required in the question. I'm not trolling: using rm is a valid requirement if, for example, you want to use -i for interactive delete... -
I would use:
find . -maxdepth 1 -type f -newerct 'jan 1' -print0 \ | xargs -0 rm(or
-newermtif you want to filter on modification time)Note that the 't' form of -newerXY will allegedtly allow any date format compatible with cvs (see doco).
0 comments:
Post a Comment