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

Related Tags