Frage

Ich verwende OpenMCL auf Darwin, und ich möchte so etwas wie zu tun:

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

Aber ich kann nicht directory bekommen etwas anderes als NIL zurückzukehren, und ich kann nicht online jede gute Erklärung zu finden scheinen (anders als „seine verschiedenen für jedes System“).

Alle Zeiger?

War es hilfreich?

Lösung

Gibt es in Ihrem Pfad Spezifikation enthält einen Platzhalter? Common Lisp des Pfadname Zeug ist etwas hart auf den ersten Blick zu erfassen - zumindest für mich war es ... Als CLHS Staaten auf der directory Funktion:

  

Wenn die Pfadangabe nicht wild ist, die   Liste resultierende enthält entweder   Null oder Eins-Elemente.

Um Ihren Pfadnamen einen Platzhalter enthalten hat, könnten Sie die Make-Pfad-Funktion versuchen, wie

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

oder auch

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

fand ich die CL-FAD Bibliothek eine große Hilfe für mit Pfadnamen und dem Dateisystem zu tun . Insbesondere könnte seine list-directory Funktion einfacher, die Ebene Standard directory Funktion zu verwenden, als.

Andere Tipps

Es gibt grundsätzlich zwei Möglichkeiten, Pfadnamen angeben:

  • mit Strings

Strings wird in Abhängigkeit offensichtlich auf der Plattform. Unix-Syntax und Windows-Syntax zum Beispiel

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

Sie können einen Pfad Objekt aus einem String erstellen:

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

Die #p versichert oben, dass ein Pfadobjekt (und kein String) erstellt wird, wenn Sie es zurück zu lesen.

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

So, intern Common Lisp arbeitet mit Pfadnamen Objekten, aber es kann Sie normale Strings verwenden und macht Pfadnamen Objekte aus ihnen, wenn nötig.

Wenn Common Lisp sieht einen Pfad, der nicht alle Komponenten angegeben (zum Beispiel das Verzeichnis fehlt) hat, dann füllt es in den Komponenten aus dem Pfad-Objekt, das den Wert der Variabel * STANDARD-PATHNAME-DEFAULTS ist *.

Mit der Funktion beschreiben, die Sie bei den Komponenten eines Pfadnamen aussehen können (hier Clozure CL):

? (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
  • mit den Lisp Funktionen Pfadnamen Objekte erstellen

MAKE-PATHNAME ist die Funktion und es dauert ein paar Keyword-Argumente, die Komponenten angeben.

Manchmal ist es auch sinnvoll, einen neuen Pfad zu erstellen, basierend auf einer vorhandenen:

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

Wenn Sie Verzeichnis es sinnvoll ist, einen Pfad mit Platzhalter zu verwenden. Verzeichnis dann eine Liste passender Pfadnamen zurück. Der Name ‚Verzeichnis‘ ist etwas irreführend, da Verzeichnisliste nicht den Inhalt eines Verzeichnisses, sondern listet die passende Pfadnamen für (in der Regel) ein Pfadname mit Wildcards. Die Platzhalter-A-Sequenzen von Zeichen in Komponenten wie /foo/s*c/list*.l* mithalten kann“. Es gibt auch die Wild Card **, die verwendet wird, Teile einer Verzeichnishierarchie passen wie / foo / ** /test.lisp, das passt auf alle Dateien test.lisp unter dem Verzeichnis foo und dessen Unterverzeichnissen.

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

Vor zurückkehren sollte eine Liste aller 'Lispeln' Dateien in '/ Users / foo / Lisp /' und alle Unterverzeichnisse.

die .c-Dateien in einer einzigen Verzeichnis Verwendung zurückzukehren:

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

Beachten Sie, dass DIRECTORY eine Liste von Pfadobjekten zurückgibt (nicht eine Liste von Strings).

? (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")

Vor verwendet ein Pfad-Objekt, das von MAKE-PATHNAME erstellt wird. Es gibt alle Dateien, die /Lisp/cl-http/cl-http-342/server/md5.* entsprechen.

Dies ist das gleiche wie:

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

, die kürzer ist, hängt aber von der Unix Pfadsyntax.

Die moderne Common Lisp Bibliothek, die Verzeichnisliste ist iolib .

Es funktioniert wie folgt:

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")

Beachten Sie, dass kein Schrägstrich oder Platzhalter erforderlich ist. Es ist sehr robust und kann sogar Prozess Dateinamen mit falsch codierten Unicode-Zeichen.

Die Unterschiede im Vergleich zu CL-FAD:

  • Die Objekte, die Sie erhalten, sind iolib Dateipfade, ein Ersatz für Pfadnamen CL, das ist näher, was das zugrunde liegende Betriebssystem der Fall ist.
  • iolib implementiert seine Routinen CFFI verwenden, so funktioniert es das gleiche auf allen Lisp-Implementierungen (vorausgesetzt iolib ein Backend für das Betriebssystem hat), im Gegensatz zu-FAD CL, die sich über die Verzeichnisfunktion der Umsetzung mit allen zu abstrahieren versucht, seine Macken.
  • Im Gegensatz zu CL-FAD, iolib Angeboten korrekt mit Symlinks (einem großen Problem mit CL-FAD, dass es praktisch unbrauchbar auf anderen Plattformen als Windows-IMHO macht).

Ich werde ein Beispiel hinzufügen, die für mich, im Interesse eines Code-Schnipsel funktioniert. Ich benutze osicat (ähnlich cl-FAD) und str .

Bearbeiten : auch mit uiop:directory-files. str: enthält? konnte mit search erfolgen.

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

Rückkehr

(#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")

Es kann sicherlich meine eine richtige Verwendung von Wildcards verbessert werden. Jedoch, dass ein Ausschnitt ist können Sie jetzt nutzen:)

Referenzen:

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top