web-dev-qa-db-fra.com

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 affiche le nom de fichier complet de chaque fichier dans le répertoire test. Existe-t-il un moyen Groovy d'obtenir le nom de fichier sans aucune extension? (Ou suis-je de retour en terre regex?)

46
Electrons_Ahoy

Je pense que la manière la plus groovy serait:

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

ou avec une expression rationnelle simple:

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

il y a aussi une librairie Apache commons-io Java lib à cette fin, dont vous pourriez facilement dépendre si vous utilisez maven:

org.Apache.commons.io.FilenameUtils.getBaseName(file.name)
47
Nikita Volkov

La manière la plus propre.

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

30
Pier
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, le code ci-dessus s'affiche: foo Si vous voulez qu'il imprime foo.bar à la place, le code suivant y parvient.

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

La classe FilenameUtils, qui fait partie du package Apache commons io, a une solution robuste. Exemple d'utilisation:

import org.Apache.commons.io.FilenameUtils

String filename = '/tmp/hello-world.txt'
def fileWithoutExt = FilenameUtils.removeExtension(filename)

Ce n'est pas la manière groovy, mais pourrait être utile si vous avez besoin de prendre en charge de nombreux cas Edge.

5
Jay P.

Le moyen le plus simple est:

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

Le résultat est:

file.name.with.dots
4
librucha

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

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

Comme mentionné dans les commentaires, où un nom de fichier se termine et une extension commence dépend de la situation. Dans la situation ma, j'avais besoin d'obtenir le nom de base (fichier sans chemin, et sans extension) des types de fichiers suivants: {foo.Zip, bar/foo.tgz, foo.tar.gz} => tous doivent produire "foo" comme extension de nom de fichier sans. (La plupart des solutions, étant donné foo.tar.gz produirait foo.tar.)

Voici une solution (évidente) qui vous donnera tout jusqu'au premier "."; facultativement, vous pouvez obtenir l'extension entière soit en morceaux ou (dans ce cas) en un seul reste (en divisant le nom de fichier en 2 les pièces). (Remarque: bien que cela ne soit pas lié à la tâche à accomplir, je supprime également le chemin d'accès 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]
1
michael

Vous pouvez mieux utiliser les expressions régulières. Une fonction comme la suivante 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].substring(1).trim().toLowerCase() : "");
  return returned_value
}
0
Alex

Remarque

import Java.io.File;

def fileNames    = [ "/a/b.c/first.txt", 
                     "/b/c/second",
                     "c:\\a\\b.c\\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 pour cet exemple - c: /test.me/firstfile

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

La meilleure approche sera de trouver la dernière occurrence de File.separator si elle est présente, puis de rechercher le nom de fichier ou l'extension.

Remarque: (Il y a une petite astuce qui se produit ci-dessous. Pour Windows, le séparateur de fichiers est \. Mais il s'agit d'un caractère spécial dans l'expression régulière et donc lorsque nous utilisons une variable contenant le File.separator dans le l'expression régulière, je dois y échapper. C'est pourquoi je fais ceci:

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

J'espère que cela a du sens :)

Essayez ceci:

import Java.io.File;

String 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"
0
Sajumon Joseph