033-basename 程序

经常写 shell 脚本的同学一定用过一个名为 basename 的程序。这个程序可以把一个路径里最后一部分提取出来,像下面这样:


这里写图片描述
图1 basename 运行结果

接下来你懂的,用 go 来实现这个 basename 程序。

本文的程序路径是:gopl/basictypes/basename

1. 版本一

package main

import (
    "fmt"
    "os"
)

func main() {
    if len(os.Args) <= 1 {
        usage()
        os.Exit(-1)
    }

    s := basename(os.Args[1])
    fmt.Println(s)
}

func basename(s string) string {
    // 处理只有一个 "/" 的情况
    if len(s) == 1 && s[0] == '/' {
        return s
    }

    // 最后一个字符是 '/' 则跳过
    if len(s) > 0 && s[len(s)-1] == '/' {
        s = s[:len(s)-1]
    }

    for i := len(s) - 1; i >= 0; i-- {
        if s[i] == '/' {
            s = s[i+1:]
            break
        }
    }

    return s
}

func usage() {
    fmt.Println("go run basename01.go <path>")
}

2. 版本二

go 语言提供了很多有用的包,strings 包就是其中之一,这是一个字符串处理专用的包,常见的关于字符串操作,比如 trim, split, join 等全都有。下面是使用 strings 包的 LastIndexByte 方法查询最后一个 '/'.

package main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    if len(os.Args) <= 1 {
        usage()
        os.Exit(-1)
    }

    s := basename(os.Args[1])
    fmt.Println(s)
}

func basename(s string) string {
    // 处理只有一个 "/" 的情况
    if len(s) == 1 && s[0] == '/' {
        return s
    }

    // 最后一个字符是 '/' 则跳过
    if len(s) > 0 && s[len(s)-1] == '/' {
        s = s[:len(s)-1]
    }

    i := strings.LastIndexByte(s, '/')
    s = s[i+1:]
    return s
}

func usage() {
    fmt.Println("go run basename02.go <path>")
}

3. 总结

  • 熟悉 strings 包
  • Tips:

关于 string 切片有一点细节需要注意。如果一个 string s 长度是 5,我们取 s[5] 是非法的,因为越界了,但是执行切片 s[5:] 是正确的,它会返回一个空串。

猜你喜欢

转载自blog.csdn.net/q1007729991/article/details/79705899