2009-09-10 23 views
22

私はダーウィンにOpenMCLを使用していて、私のような何かをしたいと思います:Common Lispのディレクトリをどのように反復するのですか?

(loop for f in (directory "somedir") 
    collect (some-per-file-processing f)) 

をしかし、私はdirectoryNIL以外を返すために得ることができない、と私はいずれかを見つけるように見えることはできません良い説明オンライン(「各システムごとに異なる」)。

任意のポインタ?

答えて

16

パス名の指定にワイルドカードが含まれていますか? Common Lispのパス名のものが最初に把握することがやや困難である - 少なくとも私にとってはそれがあった... CLHS状態としてdirectory機能に:

PATHSPECが野生でない場合は、 結果のリストが含まれていますどちらか ゼロまたは1つの要素。私は大きな助けCL-FADライブラリを見つけ

(directory (make-pathname :directory '(:absolute "srv" "hunchentoot") :name :wild :type "lisp")) 

あるいは

(directory (make-pathname :directory '(:absolute "srv" "hunchentoot") :name :wild :type :wild)) 

よう

ワイルドカードを含んで、あなたはメイクパス名の機能を試してみてください、あなたのパス名を持つために、パス名とファイルシステムを扱うためのものです。特に、そのlist-directory関数は、標準のdirectory関数よりも使いやすいかもしれません。文字列は明らかに、プラットフォームに依存している

  • 使用して文字列

:例えば、Windowsの構文対Unixの構文

+2

うんは、私のために働いた - (ディレクトリ "パス名")(ディレクトリNILを、返さ"pathname /*.*")私に期待される結果が得られました。 – Justicle

+1

ドットを含む名前のファイルのみが必要ですか? – Svante

+0

変わった?私は実際には.hと.cppファイルの後ですが、 "pathname/*"はNILを返します。 – Justicle

26

は、基本的には、パス名を指定するには、2つの方法があります。

"/Users/foo/bar.text" is a valid pathname 
"/Users/foo/*/foo.*" is a valid pathname with two wildcards 

あなたは、文字列からパス名オブジェクトを作成することができます。

? (pathname "/Users/bar/foo.text") 
#P"/Users/bar/foo.text" 

上記#Pは、あなたがそれを読み戻す時にパス名オブジェクト(とない文字列)が、作成されることを保証します。

? #P"/Users/bar/foo.text" 
#P"/Users/bar/foo.text" 

ので、内部Common Lispはパス名オブジェクトで動作しますが、それはあなたが通常の文字列を使用することができますし、必要であれば、そこからパス名のオブジェクトになります。

Common Lispは、すべてのコンポーネントが指定されていない(たとえば、ディレクトリがない)パス名を認識すると、pathnameオブジェクトからvariabel * DEFAULT-PATHNAME-DEFAULTS *の値であるコンポーネントを埋め込みます。機能付き

(ここではClozure CL)あなたは、パス名の構成を見ることができますについて説明します。パス名を作成するLisp関数を使用して

? (describe (pathname "/Users/bar/*.text")) 
#P"/Users/bar/*.text" 
Type: PATHNAME 
Class: #<BUILT-IN-CLASS PATHNAME> 
TYPE: (PATHNAME . #<CCL::CLASS-WRAPPER PATHNAME #x3000401D03BD>) 
%PATHNAME-DIRECTORY: (:ABSOLUTE "Users" "bar") 
%PATHNAME-NAME: :WILD 
%PATHNAME-TYPE: "text" 
%PHYSICAL-PATHNAME-VERSION: :NEWEST 
%PHYSICAL-PATHNAME-DEVICE: NIL 

MAKE-PATHNAMEオブジェクト関数であり、コンポーネントを指定するためにいくつかのキーワード引数が必要です。

時には既存のものに基づいて新しいパス名を作成することも有用です:

(make-pathname :name "foo" :defaults (pathname "/Users/bar/baz.text")) 

ディレクトリを使用する場合は、ワイルドカードでパス名を使用することが有用です。 DIRECTORYは、一致するパス名のリストを返します。 'DIRECTORY'という名前は、DIRECTORYがディレクトリの内容をリストするのではなく、(通常)ワイルドカードを持つパス名の一致するパス名をリストするので、やや誤解を招きます。ワイルドカードは/foo/s*c/list*.l* "のようなコンポーネント内の一連の文字と一致することができます。/ foo/**のようなディレクトリ階層の部分と一致するために使用されるワイルドカード**もあります上記は「/ユーザ/ fooの/ Lispの/」にし、すべてのすべての「lispの」ファイルのリストを返す必要があり、ディレクトリfooとそのサブディレクトリの下にあるすべてのファイルをtest.lisp一致した。

(directory "/Users/foo/Lisp/**/*.lisp") 

/test.lisp、 。DIREこと

(directory "/Users/foo/c/src/*.c") 

注:そのサブディレクトリは

単一のディレクトリ使用中の.cファイルを戻すにはCTORYはパス名オブジェクトのリストを返します(文字列のリストではありません)。

? (directory (make-pathname 
       :name "md5" 
       :type :wild 
       :directory '(:absolute "Lisp" "cl-http" "cl-http-342" "server"))) 
(#P"/Lisp/cl-http/cl-http-342/server/md5.lisp" 
#P"/Lisp/cl-http/cl-http-342/server/md5.xfasl") 

上記では、MAKE-PATHNAMEによって作成されたパス名オブジェクトを使用しています。 /Lisp/cl-http/cl-http-342/server/md5.*に一致するすべてのファイルを返します。短いですが、Unixのパス名の構文に依存する

(directory "/Lisp/cl-http/cl-http-342/server/md5.*") 

これは同じです。

+0

+1 LISPのパス名の概要は非常に役に立ちます。 – Justicle

8

ディレクトリリストを実装する最新のCommon Lispライブラリは、IOLIBです。

それはこのように動作します:末尾のスラッシュまたはワイルドカードが必要とされていないことを

CL-USER> (iolib.os:list-directory "/etc/apt") 
(#/p/"trusted.gpg~" #/p/"secring.gpg" #/p/"trustdb.gpg" #/p/"sources.list" 
#/p/"sources.list~" #/p/"apt-file.conf" #/p/"apt.conf.d" #/p/"trusted.gpg" 
#/p/"sources.list.d") 

注意。これは非常に堅牢で、誤ってコード化されたユニコード文字でファイル名を処理することさえできます。 CL-FADに比べ

違い:あなたが得る

  • オブジェクトがIOLIBファイルパス、近い基盤となるOSが何であるCLのパス名の代替品です。
  • IOLIBはCFFIを使用してルーチンを実装しているため、すべてのLisp実装(IOLIBにオペレーティングシステムのバックエンドがある場合)では同じ動作をしますが、CL-FADとは異なり、奇妙な
  • iolibはCL-FADとは対照的に、シンボリックリンク(Windows IMHO以外のプラットフォームでは事実上使用できなくなるCL-FADの大きな問題の1つ)を正しく処理します。
1

私は、コードスニペットのために私のために働く例を追加します。私はosicat(cl-fadに似ています)とstrを使用しています。

uiop:directory-filesでもあります。 str:contains? searchで行うことができます。それは確かにワイルドカードの私の適切な使用を改善することができる

;; searching for "ref". 
(setf *data-directory* "~/books/lisp") 
(remove-if-not (lambda (it) 
        (str:contains? "ref" (namestring it))) 
       (osicat:list-directory *data-directory*)) 

戻り

(#P"~/books/lisp/common-lisp-quick-reference-clqr-a4-booklet-all.pdf" 
#P"~/books/lisp/common-lisp-quick-reference-clqr-a4-consec.pdf" 
#P"~/books/lisp/commonLisp-interactive-approach-reference-buffalo.pdf") 

。 )

参考文献:しかし、それはあなたが今使用できるスニペットです

関連する問題