2016-12-15 17 views
0

私は削除する方法を探しています。例えば、私は、私は、ファイル・実名を使用することを試みたが、それは時にデフォルトディレクトリを付加上記Elispでファイル名(パス)のダブルドットを削除するには

a/1 

から取得したいのですが、指定されたパス

a/b/c/../../1 

がある を想定指定されたパスの先頭

便利な方法はありますか?私にお知らせください。

PS:可能であれば、file-truenameを使用しないでください。

答えて

3

a/b/c/../../1実際にはパスではありません(絶対ファイル名、Emacs parlance)。パスはディレクトリで始まります。

ほとんどの場合、そのパターンは、という相対ファイル名です。何に対して? Emacsでは、デフォルトでdefault-directoryです。

実際には、絶対ファイル名(「パス」)は/a/b/c/../../1でしたか?あなたがそれを使用する場合は、あなたが言うように、file-truenameあなたが望むものを与える。そしてexpand-file-nameもそうです。

あなたが本当にあなたは、デフォルト・ディレクトリの引数として"/"expand-file-nameを使用して行うことができa/1を生成するためにa/b/c/../../1をマッサージします。あるいは、このようなfile-truename:もちろん

(defun foo (relname) 
    (let ((default-directory "/")) 
    (file-truename relname))) 

、これはないa/1、あなたに/a/1を与える:

(let ((default-directory "/")) 
    (file-truename "a/b/c/../../1")) 

もちろん名前の関数であることを使用することができます。後者が本当に必要な場合は、最初に/を削除するのにsubstringを使用してください。

(たぶん、あなたは私たちに必要なもののためのユースケースを言うことができる。それはあなたが得る提案を変更するため、より役に立つかもしれません。)

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"))) 
関連する問題