Common Lisp:绝对的相对路径

时间:2017-06-21 17:04:36

标签: common-lisp pathname

这可能是一个非常愚蠢的问题,但在使用了所有内置的路径名 - 家庭功能和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()一样工作。

3 个答案:

答案 0 :(得分:4)

UIOP

以下是UIOP关于 cl-fad 的文档: - )

  

UIOP完全取代了更好的设计和实现

大量的实现附带了UIOP(由ASDF3使用),因此它在您需要时基本上已经可用(参见"使用UIOP" DOC)。库中定义的许多函数之一是uiop:parse-unix-namestring,它理解Unix文件名的语法,而不检查路径是否指定现有文件或目录。但是,双点解析为:back:up,您的实现不一定支持。有了SBCL,就是这样,路径也得到了简化。请注意,路径名允许同时使用:back:up组件;通过仅查看路径名(它是语法向上目录)可以轻松简化:back,而:up是语义向上目录,这意味着它取决于实际的文件系统。如果文件名存在,您有更好的机会获取规范文件名。

Truename

您也可以拨打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-pdirectory-exists-p都返回绝对路径名(或nil,如果文件不存在)。