How to Get correct file base name in Golang
Created
Modified
Using filepath.Base
The number is the index of the last slash in the string. If you want to get the file's base name, use filepath.Base:
package main
import (
"fmt"
"path/filepath"
)
func main() {
path := "a/b.c.go"
fmt.Println(filepath.Base(path)) // b.c.go
}
$ go run main.go b.c.go
Using filepath.Split
Split splits path immediately following the final Separator, separating it into a directory and file name component.
package main
import (
"fmt"
"path/filepath"
)
func main() {
path := "a/b.c.go"
_, file := filepath.Split(path)
fmt.Println(file) // b.c.go
}
$ go run main.go b.c.go
The basename Function
The basename function below was inspired by the Unix shell utility of the same name. In our version, basename(s) removes any prefix of s that looks like a file system path with com- ponents separated by slashes, and it removes any suffix that looks like a file type:
package main
import (
"fmt"
)
func main() {
fmt.Println(basename("a/b.c.go")) // b.c
fmt.Println(basename("a.c.go")) // a.c
fmt.Println(basename("abc")) // abc
}
// basename removes directory components and a .suffix.
// e.g., a => a, a.go => a, a/b/c.go => c, a/b.c.go => b.c
func basename(s string) string {
// Discard last '/' and everything before.
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '/' {
s = s[i+1:]
break
}
}
// Preserve everything before last '.'.
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '.' {
s = s[:i]
break
}
}
return s
}
$ go run main.go b.c a.c abc
A simpler version uses the strings.LastIndex library function:
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println(basename("a/b.c.go")) // b.c
fmt.Println(basename("a.c.go")) // a.c
fmt.Println(basename("abc")) // abc
}
func basename(s string) string {
slash := strings.LastIndex(s, "/") // -1 if "/" not found
s = s[slash+1:]
if dot := strings.LastIndex(s, "."); dot >= 0 {
s = s[:dot]
}
return s
}
$ go run main.go b.c a.c abc