-
-
Save ivanzoid/129460aa08aff72862a534ebe0a9ae30 to your computer and use it in GitHub Desktop.
package main | |
import ( | |
"strings" | |
"path/filepath" | |
) | |
func fileNameWithoutExtension(fileName string) string { | |
return strings.TrimSuffix(fileName, filepath.Ext(fileName)) | |
} |
This is probably more efficient and straightforward.
func fileNameWithoutExtension(fileName string) string {
if pos := strings.LastIndexByte(fileName, '.'); pos != -1 {
return fileName[:pos]
}
return fileName
}
@chmike what about filenames with multiple periods like 'foo.tar.gz'?
strings.LastIndexByte
will return 'foo.tar' when you probably want 'foo'?
@missinglink My understanding and assumption is that the file extension is the letter sequence after the last point. A file name may contain dots (.e.g start with a dot).
The file extension .tar.gz should be .tgz.
@missinglink if I were writing software to handle gzipped files, then it should properly find the name to be foo.tar
after removing its .gz
extension, so yes the function should return foo.tar
. Also, what about users that make files like Footage from 04.04.83.mp4
? Presumably you don't want this function returning Footage from 04
. Extension should always be logically construed to mean "the last extension."
@chmike I hate .tgz because tar and gzip are two different things. Bothers my OCD, and my ability to find all the gzipped files in a directory. 😂 Two extensions totally makes sense to me in this case.
ok fair enough, filepath.Ext()
agrees:
The extension is the suffix beginning at the final dot in the final element of path
Bash has a few different ways of getting the extension, depending on what you want:
~% FILE="example.tar.gz"
~% echo "${FILE%%.*}"
example
~% echo "${FILE%.*}"
example.tar
~% echo "${FILE#*.}"
tar.gz
~% echo "${FILE##*.}"
gz
It may be a good safeguard to have filename go through filepath.Base() first
return strings.TrimSuffix(filepath.Base(fileName), filepath.Ext(fileName))
If the extension is static (always having a certain value), then a simple strings.CutSuffix(_,_)
does the job. Example:
filenameWithoutExt, _ := strings.CutSuffix(filename, ".go")
TrimSuffix
performs a check to make sure the suffix matches before removal. Since this is a guarantee because you are using the source string's own extension, I think this could be more efficiently written using slice notation:return fileName[:len(fileName) - len(filepath.Ext(fileName))]
One could argue that yours is more easy to read.