I have the following folders/files.
A/B/C/D/giga.txt
A/BB/
A/CC/DD/fifa.jpg
A/ZZZ/1/a.txt
A/ZZZ/2/b.png
A/ZZZ/3/
How can I code in Gradle/Groovy to delete ONLY the empty directories/subfolders.
i.e. Delete "A/BB", "A/ZZZ/3" in the above sample example. Real case has lot of such folders.
I tried
tasks.withType(Delete) { includeEmptyDirs = true }
didn't work
tasks.withType(Delete) { includeEmptyDirs = false }
didn't work
I don't want to use Gradle > calling > Ant way as that'd be my last resort. Also, don't want to delete each empty folder by writing explicit delete statement per empty folder.
Case 2:
If I run the following:
delete fileTree (dir: "A", include: "**/*.txt")
this above cmd will remove any .txt file under folder A and any subfolder under it. Now, this will make "A/ZZZ/1" a valid candidate for "empty folder" which I would want to delete as well.
Using the Javadoc for FileTree, consider the following to delete empty dirs under "A". Uses Gradle 1.11:
task deleteEmptyDirs() {
def emptyDirs = []
fileTree (dir: "A").visit { def fileVisitDetails ->
def file = fileVisitDetails.file
if (file.isDirectory() && (file.list().length == 0)) {
emptyDirs << file
}
}
emptyDirs.each { dir -> dir.delete() }
}
If you want to delete all the folders that themselves only contain empty folders, this code might help.
def emptyDirs = []
project.fileTree(dir: destdir).visit {
def File f = it.file
if (f.isDirectory() ) {
def children = project.fileTree(f).filter { it.isFile() }.files
if (children.size() == 0) {
emptyDirs << f
}
}
}
// reverse so that we do the deepest folders first
emptyDirs.reverseEach { it.delete() }
Related
I'm working on a labeling tool for ML, and I want to be able to display the contents of a random folder on a React app so I can label them.I was thinking of finding the amount of folders, searching through the last available folder, and then delete from database. Repeat on refresh. Is this possible? I haven't been able to find out how to return the amount of folders in a directory.
var folders = [];
// Create a reference under which you want to list
var listRef = storageRef.child('path/to/files');
// Find all the prefixes and items.
listRef.listAll().then(function(res) {
res.prefixes.forEach(function(folderRef) {
// All the prefixes under listRef.
folders.push(folderRef);
});
}).catch(function(error) {
// Uh-oh, an error occurred!
});
var selected = []
// Select N=5 at random
for (i=0; i < 5 && folders.length > 0 ; i++){
var index = Math.floor(Math.random() * folders.length)
selected.push(folders[index])
folders.splice(index, 1);
}
You can list the files/folders inside a bucket path. Link. And select one at random of that list.
And similarly with delete files.
I try to delete files which i can find in folderPath. But I want delete only that, which have in name "Jenkins".
How to define in list to delete only that file.?
Example :
In C:\test\test have 3 files, want delete that which have Jenkins in name :
import groovy.io.FileType
String folderPath = "C:\\test" + "\\" + "test"
def list = []
def dir = new File("$folderPath")
dir.eachFileRecurse (FileType.FILES) { file ->
list << file
}
list.each {
println it.findAll() == "Jenkins" // Just files witch include in list "Jenkins" name
}
Thanks for tips !
Here you go:
Use either of the below two:
import groovy.io.FileType
String folderPath = "C:/test/test"
new File(folderPath).eachFile (FileType.FILES) { file ->
//Delete file if file name contains Jenkins
if (file.name.contains('Jenkins')) file.delete()
}
or
Below one uses FileNameFinder class
String folderPath = "C:/test/test"
def files = new FileNameFinder().getFileNames(folderPath, '**/*Jenkins*')
println files
files.each { new File(it).delete()}
I'm trying to rename files in a directory using Groovy but I can't seem to understand how it works.
Here is my script:
import groovy.io.FileType
def dir = new File("C:/Users/דודו/Downloads/Busta_Rhymes-Genesis-(Retail)-2001-HHI")
def replace = {
if (it == '_') {
' '
}
}
String empty = ""
dir.eachFile (FileType.FILES) { file ->
String newName = file.name
newName = newName.replaceAll(~/Busta_Rhymes/, "$empty")
newName = newName.replaceAll(~/feat/, "ft")
newName = newName.replaceAll(~/-HHI/, "$empty")
newName = newName.replaceAll(~/--/, "-")
newName = newName.collectReplacements(replace)
file.renameTo newName
println file.name
}
When I run this, the names of the files aren't changed as expected. I'm wondering how could I get this to work.
There are a number of things wrong here:
Your dir variable is not the directory; it is the file inside the directory that you actually want to change. Change this line:
dir.eachFile (FileType.FILES) { file ->
to this:
dir.parentFile.eachFile (FileType.FILES) { file ->
The renameTo method does not rename the local name (I know, very counterintuitive), it renames the path. So change the following:
String newName = file.name
to this:
String newName = file.path
Now, for some reason beyond my comprehension, println file.name still prints out the old name. However, if you look at the actual directory afterwords, you will see that the file is correctly renamed in the directory.
I move a file to a folder. Is there any way to not overwrite a file with that name?
For example, folder contains a file named: file1.pdf. How can I move another file named: file1.pdf into that folder so that the name get changed to e.g. file1-1.pdf, file1-2.pdf to prevent the original file from getting overwritten.
I'm using substring to do that but it's quite long and awful code.
You could use something like this:
def save = { File dir, String name ->
int version = 1
def splitName = name.split(/\./, 0).with { it -> it.length == 1 ? [it[0], ''] : [it[0..-2].join('.'), ".${it[-1]}"] }
def rename = { String prefix, String ext -> "$prefix-$version$ext" }
while (new File(dir, name).exists()) {
name = rename(*splitName)
version++
}
println "Save the file as $name"
}
save(new File('/tmp'), 'file.txt')
Which assuming you have a file /tmp/file.txt and a file /tmp/file-1.txt already, prints out: Save the file as file-2.txt
I just have a question about writing a function that will search a directory for the most recent log in a directory. I currently came up with one, but I'm wondering if there is a better (perhaps more proper) way of doing this.
I'm currently using hdsentinel to create logs on computer and placing the log in a directory. The logs are saved like so:
/directory/hdsentinel-computername-date
ie. C:/hdsentinel-owner-2010-11-11.txt
So I wrote a quick script that loops through certain variables to check for the most recent (within the past week) but after looking at it, I'm question how efficient and proper it is to do things this way.
Here is the script:
String directoryPath = "D:"
def computerName = InetAddress.getLocalHost().hostName
def dateToday = new Date()
def dateToString = String.format('%tm-%<td-%<tY', dateToday)
def fileExtension = ".txt"
def theFile
for(int i = 0; i < 7; i++) {
dateToString = String.format('%tY-%<tm-%<td', dateToday.minus(i))
fileName = "$directoryPath\\hdsentinel-$computerName-$dateToString$fileExtension"
theFile = new File(fileName)
if(theFile.exists()) {
println fileName
break;
} else {
println "Couldn't find the file: " + fileName
}
}
theFile.eachLine { print it }
The script works fine, perhaps it has some flaws. I felt I should go ahead and ask what the typical route is for this type of thing before I continue with it.
All input is appreciated.
Though a bit messy, you could implement a multi-column sort via the 'groupBy' method (Expounding on Aaron's code)..
def today = new Date()
def recent = {file -> today - new Date(file.lastModified()) < 7}
new File('/yourDirectory/').listFiles().toList()
.findAll(recent)
.groupBy{it.name.split('-')[1]}
.collect{owner, logs -> logs.sort{a,b -> a.lastModified() <=> b.lastModified()} }
.flatten()
.each{ println "${new Date(it.lastModified())} ${it.name}" }
This finds all logs created within the last week, groups them by owner name, and then sorts according to date modified.
If you have files other than logs in the directory, you may first need to grep for files containing 'hdsentinel.'
I hope this helps.
EDIT:
From the example you provided, I cannot determine if the least significant digit in the format:
C:/hdsentinel-owner-2010-11-11.txt
represents the month or the day. If the latter, sorting by file name would automatically prioritize by owner, and then by date created (without all of the chicanery of the above code).
For Instance:
new File('/directory').listFiles().toList().findAll(recent).sort{it.name}
Hopefully this helps some..This sorts a given path by date modified in a groovier way. The lists them out.
you can limit the list, and add other conditions in the closure to get the desired results
new File('/').listFiles().sort() {
a,b -> a.lastModified().compareTo b.lastModified()
}.each {
println it.lastModified() + " " + it.name
}
As I was trying to solve a similar problem, learnt a much cleaner approach.
Define a closure for sorting
def fileSortCondition = { it.lastModified() }
And File.listFiles() has other variation which accepts FileFilter and FilenameFilter in Java, and these interfaces has a single method called accept, Implement the interface as a closure.
def fileNameFilter = { dir, filename ->
if(filename.matches(regrx))
return true
else
return false
} as FilenameFilter
And lastly
new File("C:\\Log_Dir").listFiles(fileNameFilter).sort(fileSortCondition).reverse()
Implement FileFilter interface if filtering is to be done by File attributes.
def fileFilter = { file ->
if(file.isDirectory())
return false
else
return true } as FileFilter