Using Ant, I have to delete all but the latest 2 files from a backup folder.
I tried to negate last count="2"
, but could not found the right Resources order.
Currently I am doing this :
<delete verbose="true">
<difference>
<resources>
<fileset dir="${backup}"/>
</resources>
<last count="2">
<sort>
<date/>
<resources>
<fileset dir="${backup}"/>
</resources>
</sort>
</last>
</difference>
</delete>
Is there a simpler way?
This question has lead to an Ant enhancement request that has been applied for Ant 1.9.5 (which hasn't been released, yet, at the time of this writing). Up to 1.9.4 there is no better pure-Ant solution unless you want to implement a resource collection yourself.
Starting with Ant 1.9.5 you can use
<delete verbose="true">
<allbutlast count="2">
<sort>
<date/>
<resources>
<fileset dir="${backup}"/>
</resources>
</sort>
</allbutlast>
</delete>
I would recommend using a fileset selector to choose which files should be acted upon.
If the requirement falls outside ANT's normal capabilities you can script the criteria. The following example is deleting files based on date:
- Linux removing folders older than 1 year and more than 3 files
I like the answer from Stefan Bodewig very much, and can't wait to get to Ant 1.9.6 (current version at the time of writing), but I'm locked on Ant 1.9.4. So I wrote this little thing which deletes older directories but keeps the newest 5. Maybe it's of some use for someone else too.
PS
At the time I wrote the script, I did not notice how powerful the solution suggested by Mark O'Connor is. I probably should have merged my solution into a script selector, but now it's too late. :-(
In case you wonder what this is: it's a JavaScript script, inside the "script" Ant task. I would have preferred Groovy or Ruby, but I chose JavaScript, because it was already in the tools bundle I'm currently depending on (see the Ant Library Dependencies page for more details).
<script language="javascript"> <![CDATA[
// number of directories to keep
var N = 5;
// imports
importClass(java.io.File)
importClass(java.lang.System)
// helper function
function println(msg) {
System.out.println(msg);
}
// get base directory
var baseDir = new File(project.getProperty("my.base.dir"));
println(">> " + baseDir);
// filter files, keep only directories
var allFiles = baseDir.listFiles()
var directories = new Array()
for each (var file in allFiles) {
if (file.isDirectory()) {
directories.push(file)
}
}
// comparation function by modification date, newest first
function compareByLastModified(file1, file2) {
if (file1.lastModified() < file2.lastModified()) {
return 1
}
if (file1.lastModified() > file2.lastModified()) {
return -1
}
return 0;
}
// sort list
directories.sort(compareByLastModified)
// prepare "delete" task
var delTask = project.createTask("delete");
delTask.setQuiet(true);
// Delete all directories except last N in the list
for each (var dir in directories.slice(N)) {
//println(" del " + dir.toString())
delTask.setDir(dir)
delTask.perform()
}
]]> </script>