我通过连接部分路径和目录名来手动构建Elisp中的路径字符串。不幸的是,有时路径以斜线结束,有时不是。因此,我需要在必要时在连接目录名之前插入斜杠,但不是这样。这样做的好方法是什么?
答案 0 :(得分:13)
(file-name-as-directory dir)
将返回带有斜杠的目录路径dir
,必要时添加一个,否则返回。
如果列表中有部分路径序列,则可以执行以下操作:
(let ((directory-list '("/foo" "bar/" "p/q/" "x/y"))
(file-name "some_file.el"))
(concat
(mapconcat 'file-name-as-directory directory-list "")
file-name))
"/foo/bar/p/q/x/y/some_file.el"
或者作为替代方案,如果您想在列表中包含文件名,则可以使用与directory-file-name
相反的file-name-as-directory
:
(let ((path-list '("/foo" "bar/" "p/q/" "x/y/some_file.el")))
(mapconcat 'directory-file-name path-list "/"))
"/foo/bar/p/q/x/y/some_file.el"
(如果在非目录上使用directory-file-name
不可移植,请有人纠正我吗?)
答案 1 :(得分:3)
从可疑内容的部分组装文件名的最简单方法是使用expand-file-name。例如:
(expand-file-name "foo.txt")
这个常用表单将为您提供基于default-directory的完整文件名:
/home/me/foo.txt
但如果您的变量'dir'的内容为“/ home / them / subdir”并想要使用它,请执行以下操作:
(expand-file-name "foo.txt" dir)
如果dir结束与否则无关紧要。如果你在其他平台上,并且包含另一个斜杠,那么它也会做正确的事情。你有混合吗?只需堆叠它们:
(expand-file-name "foo.txt" (expand-file-name "somesubdir" dir))
答案 2 :(得分:1)
这样的事情应该起到一个起点的作用,尽管你想要充实它以使其与平台无关等等。
(defun append-path-component (path new-part)
(if (string-match ".*/$" path)
(concat path new-part)
(concat path "/" new-part)))
按照惯例,可能有一些elisp已经做到这一点,我只是不知道。
答案 3 :(得分:1)
除非您真的关心将相对文件名保持为相对文件名,否则最好避免使用concat
并使用expand-file-name
。
答案 4 :(得分:0)
(defun* tofilename (directorylist &optional (filename nil))
"concatenate directory names into a path, with an optional file name as last part"
(concat
(mapconcat 'directory-file-name directorylist "/")
"/"
filename))
(tofilename '("~/" "Temp/") "temp.txt")
;; => "~/Temp/temp.txt"
(tofilename '("~/" "Temp/"))
;; => "~/Temp/"
(tofilename '("~/" "Temp/" "test"))
;; => "~/Temp/temp/"
答案 5 :(得分:0)