这可能是一个非常愚蠢的问题,但在使用了所有内置的路径名 - 家庭功能和cl-fad
/ pathname-utils
套餐后,我仍然可以&#39 ; t弄清楚如何将相对路径转换为绝对路径(相对于$ PWD):
; let PWD be "/very/long/way"
(abspath "../road/home"); -> "/very/long/road/home"
假设函数abspath
与Python中的os.path.abspath()
一样工作。
答案 0 :(得分:4)
以下是UIOP关于 cl-fad 的文档: - )
UIOP完全取代了更好的设计和实现
大量的实现附带了UIOP(由ASDF3使用),因此它在您需要时基本上已经可用(参见"使用UIOP" DOC)。库中定义的许多函数之一是uiop:parse-unix-namestring
,它理解Unix文件名的语法,而不检查路径是否指定现有文件或目录。但是,双点解析为:back
或:up
,您的实现不一定支持。有了SBCL,就是这样,路径也得到了简化。请注意,路径名允许同时使用:back
和:up
组件;通过仅查看路径名(它是语法向上目录)可以轻松简化:back
,而:up
是语义向上目录,这意味着它取决于实际的文件系统。如果文件名存在,您有更好的机会获取规范文件名。
您也可以拨打TRUENAME
,这可能会消除" .."路径中的组件。另请参阅20.1.3 Truenames,它解释了您可以使用不同的路径名指向同一个文件,但通常只有一个"规范"名。
答案 1 :(得分:3)
变量*DEFAULT-PATHNAME-DEFAULTS*
通常包含您的初始工作目录,您可以将路径名与其合并;
(defun abspath (pathname)
(merge-pathnames pathname *default-pathname-defaults*))
由于这是merge-pathnames
的第二个参数的默认值,因此您只需编写:
(defun abspath (pathname)
(merge-pathnames pathname))
答案 2 :(得分:2)
这是最终解决方案(基于前两个答案):
(defun abspath
(path-string)
(uiop:unix-namestring
(uiop:merge-pathnames*
(uiop:parse-unix-namestring path-string))))
uiop:parse-unix-namestring
将字符串参数转换为路径名,替换.
和..
引用; uiop:merge-pathnames*
将相对路径名转换为绝对路径名; uiop:unix-namestring
将路径名转换回字符串。
此外,如果您确定路径指向哪种文件,则可以使用:
(uiop:unix-namestring (uiop:file-exists-p path))
或
(uiop:unix-namestring (uiop:directory-exists-p path))
因为file-exists-p
和directory-exists-p
都返回绝对路径名(或nil
,如果文件不存在)。