Does groovy have an easy way to get a filename without the extension?

吃可爱长大的小学妹 提交于 2019-11-29 02:05:06

问题


Say I have something like this:

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

This prints the full filename of every file in the test directory. Is there a Groovy way to get the filename without any extension? (Or am I back in regex land?)


回答1:


I believe the grooviest way would be:

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

or with a simple regexp:

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

also there's an apache commons-io java lib for that kinda purposes, which you could easily depend on if you use maven:

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



回答2:


The cleanest way.

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




回答3:


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

This works well for file names like: foo, foo.bar

But if you have a file foo.bar.jar, then the above code prints out: foo If you want it to print out foo.bar instead, then the following code achieves that.

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



回答4:


The FilenameUtils class, which is part of the apache commons io package, has a robust solution. Example usage:

import org.apache.commons.io.FilenameUtils

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

This isn't the groovy way, but might be helpful if you need to support lots of edge cases.




回答5:


Simplest way is:

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

Result is:

file.name.with.dots



回答6:


Maybe not as easy as you expected but working:

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



回答7:


As mentioned in comments, where a filename ends & an extension begins depends on the situation. In my situation, I needed to get the basename (file without path, and without extension) of the following types of files: { foo.zip, bar/foo.tgz, foo.tar.gz } => all need to produce "foo" as the filename sans extension. (Most solutions, given foo.tar.gz would produce foo.tar.)

Here's one (obvious) solution that will give you everything up to the first "."; optionally, you can get the entire extension either in pieces or (in this case) as a single remainder (splitting the filename into 2 parts). (Note: although unrelated to the task at hand, I'm also removing the path as well, by calling file.name.)

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



回答8:


You can use regular expressions better. A function like the following would do the trick:

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
}



回答9:


Note

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}" 
}

Some of the below solutions (except the one using apache library) doesn't work for this example - c:/test.me/firstfile

If I try to find an extension for above entry, I will get ".me/firstfile" - :(

Better approach will be to find the last occurrence of File.separator if present and then look for filename or extension.

Note: (There is a little trick happens below. For Windows, the file separator is \. But this is a special character in regular expression and so when we use a variable containing the File.separator in the regular expression, I have to escape it. That is why I do this:

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

Hope it makes sense :)

Try this out:

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"



回答10:


// Create an instance of a file (note the path is several levels deep)
File file = new File('/tmp/whatever/certificate.crt')

// To get the single fileName without the path (but with EXTENSION! so not answering the question of the author. Sorry for that...)
String fileName = file.parentFile.toURI().relativize(file.toURI()).getPath()


来源:https://stackoverflow.com/questions/1569547/does-groovy-have-an-easy-way-to-get-a-filename-without-the-extension

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!