File 如何使用Elisp删除文件名(路径)中的双点
我正在寻找一种方法来移除。。并得到一条没有。 例如,假设有一条给定的路径File 如何使用Elisp删除文件名(路径)中的双点,file,emacs,path,File,Emacs,Path,我正在寻找一种方法来移除。。并得到一条没有。 例如,假设有一条给定的路径 a/b/c/../../1 那么我想从上面得到 a/1 我曾尝试使用文件truename,但它在给定路径的开头预先添加了默认目录 有什么方便的方法吗?请让我知道 PS:如果可能的话,我希望避免使用文件truename。a/b/c/../1不是真正的路径(绝对文件名,用Emacs的说法)。路径以目录开头 最多,该模式是一个相对文件名。相对于什么?在Emacs中,默认情况下,默认目录 也许你真正的意思是/a/b/c/../
a/b/c/../../1
那么我想从上面得到
a/1
我曾尝试使用文件truename,但它在给定路径的开头预先添加了默认目录
有什么方便的方法吗?请让我知道
PS:如果可能的话,我希望避免使用文件truename。
a/b/c/../1
不是真正的路径(绝对文件名,用Emacs的说法)。路径以目录开头
最多,该模式是一个相对文件名。相对于什么?在Emacs中,默认情况下,默认目录
也许你真正的意思是/a/b/c/../1
,这是一个绝对的文件名(“路径”)?如果您使用它,那么,正如您所说,filetruename
会提供您想要的。扩展文件名也是如此
如果您真的想按摩a/b/c/./../1
来生成a/1
,那么可以使用展开文件名
和“/”
作为默认目录参数。或者像这样文件truename
:
(let ((default-directory "/"))
(file-truename "a/b/c/../../1"))
当然,您可以在命名函数中使用它:
(defun foo (relname)
(let ((default-directory "/"))
(file-truename relname)))
当然,这将为您提供/a/1
,而不是a/1
。如果确实需要后者,则只需使用子字符串
删除第一个/
(也许你可以告诉我们你所需要的用例。它可能会改变你得到的建议,因此会更有帮助。)a/b/c/./../1
不是真正的路径(绝对文件名,用Emacs的说法)。路径以目录开头
最多,该模式是一个相对文件名。相对于什么?在Emacs中,默认情况下,默认目录
也许你真正的意思是/a/b/c/../1
,这是一个绝对的文件名(“路径”)?如果您使用它,那么,正如您所说,filetruename
会提供您想要的。扩展文件名也是如此
如果您真的想按摩a/b/c/./../1
来生成a/1
,那么可以使用展开文件名
和“/”
作为默认目录参数。或者像这样文件truename
:
(let ((default-directory "/"))
(file-truename "a/b/c/../../1"))
当然,您可以在命名函数中使用它:
(defun foo (relname)
(let ((default-directory "/"))
(file-truename relname)))
当然,这将为您提供/a/1
,而不是a/1
。如果确实需要后者,则只需使用子字符串
删除第一个/
(也许你可以告诉我们你所需要的用例。它可能会改变你得到的建议,从而更有帮助。)你可以使用简单的字符串操作来实现这一点。因此,您不需要使用仅当文件实际存在于文件系统中时才起作用的函数
下面的函数拆分/
:s上的字符串,并遍历结果列表。它忽略任何
,并且每当它看到。
时,它就会出现在已经看到的路径组件上
例如:
(defun my-simplify-path (path)
"Simplify PATH by removing redundant parts.
The operation is only performed using string operations, so PATH
does not have to exist in the file system."
(let ((old-list (split-string path "/"))
(new-list-reversed '()))
(dolist (element old-list)
(cond ((equal element "."))
((and (equal element "..")
(not (null new-list-reversed)))
(pop new-list-reversed))
(t
(push element new-list-reversed))))
(if (null new-list-reversed)
"."
(string-join (nreverse new-list-reversed) "/"))))
以下ERT测试用例演示了此函数的工作原理:
(ert-deftest my-simplify-path-test ()
(should (equal (my-simplify-path "alpha") "alpha"))
(should (equal (my-simplify-path "./alpha") "alpha"))
(should (equal (my-simplify-path "alpha/./beta") "alpha/beta"))
(should (equal (my-simplify-path "alpha/beta") "alpha/beta"))
(should (equal (my-simplify-path "alpha/../beta") "beta"))
(should (equal (my-simplify-path "alpha/beta/gamma/delta/../../..") "alpha"))
(should (equal (my-simplify-path "../alpha") "../alpha"))
(should (equal (my-simplify-path "alpha/../..") ".."))
(should (equal (my-simplify-path "a/b/c/../../1") "a/1")))
您可以使用普通字符串操作来实现这一点。因此,您不需要使用仅当文件实际存在于文件系统中时才起作用的函数
下面的函数拆分/
:s上的字符串,并遍历结果列表。它忽略任何
,并且每当它看到。
时,它就会出现在已经看到的路径组件上
例如:
(defun my-simplify-path (path)
"Simplify PATH by removing redundant parts.
The operation is only performed using string operations, so PATH
does not have to exist in the file system."
(let ((old-list (split-string path "/"))
(new-list-reversed '()))
(dolist (element old-list)
(cond ((equal element "."))
((and (equal element "..")
(not (null new-list-reversed)))
(pop new-list-reversed))
(t
(push element new-list-reversed))))
(if (null new-list-reversed)
"."
(string-join (nreverse new-list-reversed) "/"))))
以下ERT测试用例演示了此函数的工作原理:
(ert-deftest my-simplify-path-test ()
(should (equal (my-simplify-path "alpha") "alpha"))
(should (equal (my-simplify-path "./alpha") "alpha"))
(should (equal (my-simplify-path "alpha/./beta") "alpha/beta"))
(should (equal (my-simplify-path "alpha/beta") "alpha/beta"))
(should (equal (my-simplify-path "alpha/../beta") "beta"))
(should (equal (my-simplify-path "alpha/beta/gamma/delta/../../..") "alpha"))
(should (equal (my-simplify-path "../alpha") "../alpha"))
(should (equal (my-simplify-path "alpha/../..") ".."))
(should (equal (my-simplify-path "a/b/c/../../1") "a/1")))