kurumi-bioの雑記帳

プログラミング、パソコン、ペット、 犬、お出かけ

初心者のGo言語 -41- <Base,Clean,Dir,Ext>

こんにちは、kurumi-bioです。
第1回目のpathパッケージ(標準ライブラリー)の学習です。

前回の記事

kurumi-bio.hatenablog.com

APIリファレンス(過去記事の一覧)

kurumi-bio.hatenablog.com

環境

  • Windows
    OSバージョン:Windows11 Home 22H2
    Go言語のバージョン:go version go1.20.3 windows/amd64
  • Linux
    OSバージョン:openSUSE Leap 15.4
    Go言語のバージョン:go version go1.20.3 linux/amd64

Base関数

func Base(path string) string

関数の説明 Base はパスの最後の要素を返します。末尾のスラッシュは、最後の要素を抽出する前に削除されます。パスが空の場合、Base は「.」を返します。パス全体がスラッシュで構成されている場合、Base は「/」を返します。

package main

import (
    "fmt"
    "path"
    "path/filepath"
)

func printBase(pathString string) {
    fmt.Printf("[%s] -> [%s]\n", pathString, path.Base(pathString))
}

func main() {
    fmt.Printf("separator=[%s]\n", string(filepath.Separator))
    //Windows Path
    printBase("C:\\test1\\test1.go")
    printBase("\\test2\\test2-1")
    printBase("\\test3\\test3-1\\")
    printBase("\\test4\\test4-1\\..")
    printBase("c:\\test5\\..\\test5-1")
    printBase("\\test6\\..\\..\\test6-1")
    //Linux Path
    printBase("C:/test1/test1.go")
    printBase("/test2/test2-1")
    printBase("/test3/test3-1/")
    printBase("/test4/test4-1/..")
    printBase("c:/test5/../test5-1")
    printBase("/test6/../../test6-1")
}

コードの説明 標準出力にパスの階層文字を出力します。
その後、色々なパスをpath.Base()関数に渡して得られた結果を標準出力に出力します。

◆実行結果(Windows)

◆実行結果(Linux)

実行結果の説明 Windows環境とLinux環境では、パスの階層文字が異なっており、Windows\で、Linux/でした。
path.Base()関数は、WindowsLinuxの両環境でパスと認識するのは/でした。
そのため、Windows環境で階層文字に'\'を記載しても最後の要素が抽出されませんでした。

Clean関数

func Clean(path string) string

関数の説明 Clean は、純粋に字句処理によって path に相当する最短のパス名を返します。それ以上の処理ができなくなるまで、次のルールが繰り返し適用されます。

複数のスラッシュを 1 つのスラッシュに置き換えます。 それぞれを削除します。パス名要素 (現在のディレクトリ)。 内部の各 .. パス名要素 (親ディレクトリ) と、その前にある非 .. 要素を削除します。 ルートパスの先頭にある .. 要素を削除します。つまり、パスの先頭にある「/..」を「/」に置き換えます。 返されるパスは、ルート「/」である場合にのみスラッシュで終わります。

このプロセスの結果が空の文字列の場合、Clean は文字列「.」を返します。

Rob Pike、「Lexical File Names in Plan 9 or Getting Dot-Dot Right」 https://9p.io/sys/doc/lexnames.html も参照してください。

package main

import (
    "fmt"
    "path"
)

func printClean(pathString string) {
    fmt.Printf("[%s] -> [%s]\n", pathString, path.Clean(pathString))
}
func main() {
    //Windows Path
    printClean("C:\\test1\\test1.go")
    printClean("\\test2\\test2-1")
    printClean("\\test3\\test3-1\\")
    printClean("\\test4\\test4-1\\..")
    printClean("c:\\test5\\..\\test5-1")
    printClean("\\test6\\..\\..\\test6-1")
    //Linux Path
    printClean("C:/test1/test1.go")
    printClean("/test2/test2-1")
    printClean("/test3/test3-1/")
    printClean("/test4/test4-1/..")
    printClean("c:/test5/../test5-1")
    printClean("/test6/../../test6-1")
}

コードの説明 標準出力にパスの階層文字を出力します。
その後、色々なパスをpath.Clean()関数に渡して得られた結果を標準出力に出力します。

◆実行結果(Windows)

◆実行結果(Linux)

実行結果の説明 path.Clean()関数もWindowsLinuxの両環境でパスと認識するのは/でした。

Dir関数

func Dir(path string) string

関数の説明 Dir は、パスの最後の要素を除くすべての要素 (通常はパスのディレクトリ) を返します。 Split を使用して最後の要素を削除した後、パスがクリーンアップされ、末尾のスラッシュが削除されます。パスが空の場合、Dir は「.」を返します。パス全体がスラッシュとそれに続く非スラッシュ バイトで構成されている場合、Dir は 1 つのスラッシュを返します。それ以外の場合、返されるパスはスラッシュで終わりません。

package main

import (
    "fmt"
    "path"
)

func printDir(pathString string) {
    fmt.Printf("[%s] -> [%s]\n", pathString, path.Dir(pathString))
}

func main() {
    //Windows Path
    printDir("C:\\test1\\test1.go")
    printDir("\\test2\\test2-1")
    printDir("\\test3\\test3-1\\")
    printDir("\\test4\\test4-1\\..")
    printDir("c:\\test5\\..\\test5-1")
    printDir("\\test6\\..\\..\\test6-1")
    //Linux Path
    printDir("C:/test1/test1.go")
    printDir("/test2/test2-1")
    printDir("/test3/test3-1/")
    printDir("/test4/test4-1/..")
    printDir("c:/test5/../test5-1")
    printDir("/test6/../../test6-1")
}

コードの説明 標準出力にパスの階層文字を出力します。
その後、色々なパスをpath.Dir()関数に渡して得られた結果を標準出力に出力します。

◆実行結果(Windows)

◆実行結果(Linux)

実行結果の説明 path.Dir()関数も、WindowsLinuxの両環境でパスと認識するのは/でした。
そのため、階層文字に\を記載するとパスが"空"とみなされて"."が返ってきました。

Ext関数

func Ext(path string) string

関数の説明 Ext は、パスで使用されるファイル名拡張子を返します。拡張子は、パスの最後のスラッシュで区切られた要素の最後のドットから始まるサフィックスです。ドットがない場合は空です。

package main

import (
    "fmt"
    "path"
)

func printExt(pathString string) {
    fmt.Printf("[%s] -> [%s]\n", pathString, path.Ext(pathString))
}

func main() {
    printExt("c:/test/test.bat")
    printExt("test")
    printExt("/test/test.bat.txt")
    printExt("/test/test.bat.")
    printExt("c:/test/test.bat.txt/")
}

コードの説明 色々なパスをpath.Ext()関数に渡して得られた結果を標準出力に出力します。

◆実行結果(Windows)

◆実行結果(Linux)

実行結果の説明 最後の"."から後ろの文字列が拡張子として得られました。
"."が無い場合、最後の文字列が"/"の場合は、空が返ってきました。

最後までご覧いただきありがとうございます