Groovy a-t-il un moyen facile d’obtenir un nom de fichier sans l’extension?

Disons que j’ai quelque chose comme ça:

new File("test").eachFile() { file-> println file.getName() } 

Ceci imprime le nom de fichier complet de chaque fichier du répertoire de test . Existe-t-il un moyen Groovy pour obtenir le nom du fichier sans aucune extension? (Ou suis-je de retour dans une terre de regex?)

Je crois que la manière la plus sage serait:

 file.name.lastIndexOf('.').with {it != -1 ? file.name[0.. 

ou avec une expression rationnelle simple:

 file.name.replaceFirst(~/\.[^\.]+$/, '') 

il y a aussi une librairie apache commons-io java pour ce genre de choses, sur laquelle vous pouvez facilement compter si vous utilisez maven:

 org.apache.commons.io.FilenameUtils.getBaseName(file.name) 

Le moyen le plus propre

Ssortingng fileWithoutExt = file.name.take(file.name.lastIndexOf('.'))

 new File("test").eachFile() { file-> println file.getName().split("\\.")[0] } 

Cela fonctionne bien pour les noms de fichiers comme: foo, foo.bar

Mais si vous avez un fichier foo.bar.jar, alors le code ci-dessus s’imprime: foo Si vous voulez que foo.bar soit imprimé, le code suivant est atteint.

 new File("test").eachFile() { file-> def names = (file.name.split("\\.") def name = names.size() > 1 ? (names - names[-1]).join('.') : names[0] println name } 

Peut-être pas aussi facile que prévu mais en travaillant:

 new File("test").eachFile { println it.name.lastIndexOf('.') >= 0 ? it.name[0 .. it.name.lastIndexOf('.')-1] : it.name } 

La classe FilenameUtils, qui fait partie du package apache commons io, possède une solution robuste. Exemple d’utilisation:

 import org.apache.commons.io.FilenameUtils Ssortingng filename = '/tmp/hello-world.txt' def fileWithoutExt = FilenameUtils.removeExtension(filename) 

Ce n’est pas la bonne façon, mais cela peut être utile si vous avez besoin de prendre en charge de nombreux cas extrêmes.

Comme mentionné dans les commentaires, où un nom de fichier se termine et une extension commence en fonction de la situation. Dans ma situation, je devais obtenir le nom de base (fichier sans chemin d’access et sans extension) des types de fichiers suivants: { foo.zip , bar/foo.tgz , foo.tar.gz } => tous doivent produire ” foo “comme nom de fichier sans extension. (La plupart des solutions, étant donné que foo.tar.gz produirait foo.tar .)

Voici une (évidente) solution qui vous donnera tout ce que vous avez à faire “.” en option, vous pouvez obtenir l’intégralité de l’extension soit en morceaux, soit (dans le cas présent) sous la forme d’un rest unique (division du nom de fichier en 2 parties). (Remarque: bien que non lié à la tâche à accomplir, je supprime également le chemin en appelant file.name .)

 file=new File("temp/foo.tar.gz") file.name.split("\\.", 2)[0] // => return "foo" at [0], and "tar.gz" at [1] 

Le moyen le plus simple est:

 'file.name.with.dots.tgz' - ~/\.\w+$/​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 

Le résultat est:

 file.name.with.dots 

Vous pouvez utiliser les expressions régulières mieux. Une fonction comme celle-ci ferait l’affaire:

 def getExtensionFromFilename(filename) { def returned_value = "" m = (filename =~ /(\.[^\.]*)$/) if (m.size()>0) returned_value = ((m[0][0].size()>0) ? m[0][0].subssortingng(1).sortingm().toLowerCase() : ""); return returned_value } 

Remarque

 import java.io.File; def fileNames = [ "/a/bc/first.txt", "/b/c/second", "c:\\a\\bc\\third...", "c:\\a\b\\c\\.text" ] def fileSeparator = ""; fileNames.each { // You can keep the below code outside of this loop. Since my example // contains both windows and unix file structure, I am doing this inside the loop. fileSeparator= "\\" + File.separator; if (!it.contains(File.separator)) { fileSeparator = "\\/" } println "File extension is : ${it.find(/((?<=\.)[^\.${fileSeparator}]+)$/)}" it = it.replaceAll(/(\.([^\.${fileSeparator}]+)?)$/,"") println "Filename is ${it}" } 

Certaines des solutions ci-dessous (à l'exception de celle utilisant la bibliothèque apache) ne fonctionnent pas dans cet exemple - c: /test.me/firstfile

Si j'essaie de trouver une extension pour l'entrée ci-dessus, j'obtiendrai ".me / firstfile" - 🙁

Une meilleure approche consistera à trouver la dernière occurrence de File.separator si elle est présente, puis à rechercher le nom de fichier ou l’extension.

Note: (Il y a un petit truc qui se passe ci-dessous. Pour Windows, le séparateur de fichier est \. Mais c'est un caractère spécial dans les expressions régulières et donc quand on utilise une variable contenant le fichier File.separator dans l'expression régulière C'est pour ça que je fais ça:

 def fileSeparator= "\\" + File.separator; 

J'espère que c'est logique 🙂

Essayez ceci:

 import java.io.File; Ssortingng strFilename = "C:\\first.1\\second.txt"; // Few other flavors // strFilename = "/dd/dddd/2.dd/dio/dkljlds.dd" def fileSeparator= "\\" + File.separator; if (!strFilename.contains(File.separator)) { fileSeparator = "\\/" } def fileExtension = ""; (strFilename =~ /((?<=\.)[^\.${fileSeparator}]+)$/).each { match, extension -> fileExtension = extension } println "Extension is:$fileExtension" 
 // Create an instance of a file (note the path is several levels deep) File file = new File('/tmp/whatever/certificatee.crt') // To get the single fileName without the path (but with EXTENSION! so not answering the question of the author. Sorry for that...) Ssortingng fileName = file.parentFile.toURI().relativize(file.toURI()).getPath()