2012-03-14 6 views
9

部分パスとディレクトリ名を連結して、Elispでパス文字列を手動で構築しています。残念なことに、パスはスラッシュで終わることもあります。したがって、必要に応じてディレクトリ名を連結する前にスラッシュを挿入する必要がありますが、それ以外の場合は挿入しないでください。これを行うには良い方法は何ですか?通常通りElispでは、スラッシュを正しく挿入してパス文字列を取得する方法は?

+0

(Linux上では、ファイルパス内の二重シンボルは通常は/と解釈されます)、余分なものは問題にならないはずです。 – Tyler

+0

これはすべてのプラットフォームで動作する必要があります。 – qazwsx

答えて

12

(file-name-as-directory dir)は、ディレクトリパスdirに後ろにスラッシュを付け、必要に応じて1つ追加します。あなたは、リスト内のファイル名を含めたい場合

(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を使用している場合誰かが私を修正してください)

+0

「/」で始まる部分がある場合はどうなりますか? ''/p/q/''? – qazwsx

+0

開始時であれば問題ありません(上記の私の例)。開始時でない場合、絶対パスはパスコンポーネントのシーケンスの途中にあるビジネスを持たないため、そのシーケンスを生成したロジックにバグがあることが示唆されます。 – phils

+0

econdの例で明示的に "/"を使用していることは移植性の問題ではありませんか? –

1

このような何かあなたはそれがプラットフォームに依存するために少しそれを肉付けしたいと思いますが、出発点として動作するはず、など

(defun append-path-component (path new-part) 
    (if (string-match ".*/$" path) 
    (concat path new-part) 
    (concat path "/" new-part))) 

、elispのいくつかのビットは、おそらくありますそれはすでに私が気づいていないことをしています。

+0

ありがとうございます。また、私はそれらの可能性のある既存の内蔵機能を探していました。 – qazwsx

+0

これは移植性に問題があります。あなたは、あなたのlispコードに別々のパスを入力する必要はありません。 –

+0

event_jr: 'directory-sep-char'は古くなっており、Emacs 24で完全に削除されました。古いdocstringは"この値は常に '?/'です。 " – phils

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/" 
3

問題のあるコンテンツの一部からファイル名をアセンブルする最も簡単な方法は、expand-file-nameです。たとえば:

(expand-file-name "foo.txt") 

は、この一般的な形式は、デフォルトのディレクトリに基づいてあなたの完全なファイル名を与えます:

/home/me/foo.txt 

ができますが、その内容は「/ホーム/彼らはある変数「DIR」を持っている場合/ subdir "を使用したい場合は、次のようにしてください:

(expand-file-name "foo.txt" dir) 

dirが終了するかどうかは関係ありません。あなたが他のプラットホームにいて、他のスラッシュを含んでいれば、正しいこともします。ミックスはありますか?ちょうどそれらをスタック:

(expand-file-name "foo.txt" (expand-file-name "somesubdir" dir)) 
1

をあなたは本当に相対として相対ファイル名を保つことを気にしない限り、それは常により良いconcatを避け、代わりにexpand-file-nameを使用することがあります。

+0

2つの違いを説明する例を教えてください。 – qazwsx

0

ファイル操作、ファイルパスの結合と分割、空のディレクトリのチェックなどを行う場合は、最新のファイル操作ライブラリf.elをインストールすることを強くお勧めします。あなたは1つの名前空間の下でファイルとファイルパスの操作機能の巨大なセットを持って、決して再び車輪を再発明しません。

必要な機能は、f-joinです。パスの一部を連結し、必要な場合のみスラッシュを追加します。

関連する問題