Guile色々/パス名の処理

変更履歴

概 要

目 次

参考資料

ディレクトリ部の抽出

(dirname path)

path からディレクトリ部(最後のスラッシュより前の部分)を抽出して返します.path がスラッシュを含まない場合,カレントディレクトリを表す "." を返します.path はファイル名やディレクトリ名を表す文字列です.

この手続きは純粋に文字列の処理を行っているだけで, 実体としてのファイルやディレクトリとは無関係です. 例えば,実体が存在しないパス名を指定しても,そのディレクトリ部を返します.

▹実行例:以下の non-exist というディレクトリは存在しません.dirname 手続きの処理はファイルやディレクトリの実体とは無関係です.
$ guile
GNU Guile 3.0.5
      ...... 起動メッセージ ......
guile> (dirname "/home/algo/not-exist/somefile.txt")
$1 = "/home/algo/not-exist"
guile> (dirname "/home/algo/not-exist")
$2 = "/home/algo"
guile> (dirname "not-exist/somefile.txt")
$3 = "not-exist"
guile> (dirname "somefile.txt")
$4 = "."
パス名の前後に空白があってもトリミングはしません. さらに,パス名の最後にスラッシュが入ると挙動が変化します.
guile> (dirname "/home/algo/not-exist ")
$5 = "/home/algo"
guile> (dirname "/home/algo/not-exist/ ")
$6 = "/home/algo/not-exist"
ディレクトリ名に空白が入っていても問題なく抽出するようです.
guile> (dirname "/home/algo/not exist/somefile.txt")
$7 = "/home/algo/not exist"
guile> 

ベース部の抽出

(basename path)
(basename path suffix)

path からベース部(最後のスラッシュの後ろの部分)を抽出して返します.さらに,suffix を指定して,かつ, ベース部の末尾が suffix に一致した場合,suffix も削除して返します.path はファイル名やディレクトリの名を表す文字列,suffix はファイルの拡張子を表す文字列です.

dirname 手続きと同様に, この手続きは純粋に文字列の処理を行っているだけで, 実体としてのファイルやディレクトリとは無関係です.

▹ 実行例:以下の non-exist というディレクトリは存在しません.basename 手続きの処理はファイルやディレクトリの実体とは無関係です.
guile> (basename "/home/algo/not-exist/somefile.txt")
$1 = "somefile.txt"
guile> (basename "/home/algo/not-exist/somefile.txt" "txt")
$2 = "somefile."
guile> (basename "/home/algo/not-exist/somefile.txt" "scm")
$3 = "somefile.txt"
guile> (basename "/home/algo/not-exist")
$4 = "not-exist"
guile> (basename "/home/algo/not-exist/")
$5 = "not-exist/"
dirname 手続きと同様に, パス名の前後に空白があってもトリミングはしません. さらに,パス名の最後にスラッシュが入ると挙動が変化します.
guile> (basename "/home/algo/not-exist ")
$6 = "not-exist "
guile> (basename "/home/algo/not-exist/ ")
$7 = " "
guile> 

ファイル名・ディレクトリ名の正規化

(canonicalize-path path)

path が表すファイルやディレクトリの絶対パスを返します. 返り値の絶対パスは,"." や ".." や 多重のスラッシュ(//など)やシンボリックリンクをいっさい含みません.path はファイル名やディレクトリ名を表す文字列です.

dirname や basename とは違って,path が表すファイルやディレクトリは存在していなければなりません.存在しない場合,エラーが発生します.

シンボリックリンクをすべて辿った先の,実体としてのファイルやディレクトリの絶対パスを返します.

▹実行例:次のようなディレクトリ(ホームディレクトリ上のtemp)の上で色々と試してみます.
$ pwd
/home/algo/temp
$ ls -lR .
.:
lrwxrwxrwx 1 algo algo   16  2月 15 16:40 bbb.lnk -> temp-bbb/bbb.txt
lrwxrwxrwx 1 algo algo   12  2月 15 16:45 somefile.lnk -> somefile.txt
-rw-r--r-- 1 algo algo   22  2月 15 16:44 somefile.txt
drwxr-xr-x 2 algo algo 4096  2月 15 16:40 temp-aaa/
lrwxrwxrwx 1 algo algo    8  2月 15 16:56 temp-aaa-lnk -> temp-aaa/
drwxr-xr-x 2 algo algo 4096  2月 15 16:40 temp-bbb/

./temp-aaa:
lrwxrwxrwx 1 algo algo  7  2月 15 16:40 aaa.lnk -> aaa.txt
-rw-r--r-- 1 algo algo 22  2月 15 16:44 aaa.txt

./temp-bbb:
-rw-r--r-- 1 algo algo 22  2月 15 16:44 bbb.txt
まず,通常ファイルやディレクトリを指定してみます.
guile> (canonicalize-path "somefile.txt")
$1 = "/home/algo/temp/somefile.txt"
guile> (canonicalize-path "temp-aaa")
$2 = "/home/algo/temp/temp-aaa"
guile> (canonicalize-path "temp-aaa/aaa.txt")
$3 = "/home/algo/temp/temp-aaa/aaa.txt"
次に,シンボリックリンクを色々と試してみます. 最後の結果($7)は,すべてのシンボリックリンクを辿った先のファイルの絶対パスが返ってきています.
guile> (canonicalize-path "somefile.lnk")
$4 = "/home/algo/temp/somefile.txt"
guile> (canonicalize-path "bbb.lnk")
$5 = "/home/algo/temp/temp-bbb/bbb.txt"
guile> (canonicalize-path "temp-aaa-lnk")
$6 = "/home/algo/temp/temp-aaa"
guile> (canonicalize-path "temp-aaa-lnk/aaa.lnk")
$7 = "/home/algo/temp/temp-aaa/aaa.txt"
guile> 
やや極端な実行例を示します.
guile> (canonicalize-path "./temp-aaa-lnk//../temp-bbb/../temp-aaa-lnk/./aaa.lnk")
$8 = "/home/algo/temp/temp-aaa/aaa.txt"
guile> 

存在しないファイルやディレクトリを指定するとエラーが発生します.
guile> (canonicalize-path "temp-bbb/ccc.txt")
ice-9/boot-9.scm:1669:16: In procedure raise-exception:
In procedure canonicalize-path: そのようなファイルやディレクトリはありません

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
guile [1]> 
(おしまい)