2009-09-10 8 views
22

मैं डार्विन पर OpenMCL उपयोग कर रहा हूँ, और मैं कुछ ऐसा करना चाहते हैं:मैं सामान्य लिस्प में निर्देशिका के माध्यम से कैसे पुन: प्रयास करूं?

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

लेकिन मैं directory अन्य कुछ भी वापस जाने के लिए NIL से नहीं मिल सकता है, और मैं किसी भी खोजने के लिए नहीं कर पा रहे अच्छी व्याख्या ऑनलाइन ("प्रत्येक प्रणाली के लिए अलग" के अलावा)।

कोई बात नहीं?

उत्तर

16

क्या आपके पथनाम विनिर्देश में वाइल्डकार्ड है? कॉमन लिस्प के पथ सामान पहली बार में समझ में कुछ हद तक कठिन है - directory समारोह पर कम से कम मेरे लिए यह था ... CLHS राज्यों के रूप में:

pathspec जंगली नहीं है, तो जिसके परिणामस्वरूप सूची में शामिल होंगे या तो शून्य या एक तत्व।

आदेश में अपने पथ के लिए एक वाइल्डकार्ड में शामिल हैं, आप मेकअप पथ समारोह की कोशिश कर सकते,

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

या यहां तक ​​कि

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

की तरह मैंने पाया CL-FAD पुस्तकालय एक बहुत मदद पथनाम और फ़ाइल सिस्टम से निपटने के लिए। विशेष रूप से, list-directory फ़ंक्शन सादे मानक directory फ़ंक्शन से उपयोग करना आसान हो सकता है।

  • तार का उपयोग कर

स्ट्रिंग्स स्पष्ट रूप से मंच के आधार पर कर रहे हैं: यूनिक्स वाक्य रचना बनाम उदाहरण के लिए विंडोज वाक्य रचना

+2

हाँ मेरे लिए काम किया - (निर्देशिका "पथ") लौटे शून्य है, जहां (निर्देशिका "पथनाम /*.*") ने मुझे अपेक्षित परिणाम दिए। – Justicle

+1

आपको केवल डॉट वाले नाम वाली फाइलों की आवश्यकता है? – Svante

+0

अजीब हुह? मैं वास्तव में .h और .cpp फ़ाइलों के बाद हूं, लेकिन "पथनाम/*" शून्य लौटाता है। – Justicle

26

मूल रूप से pathnames निर्दिष्ट करने के लिए दो तरीके हैं। ,

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

#p ऊपर भरोसा दिलाते हैं कि एक पथ वस्तु (और नहीं एक स्ट्रिंग) बनाया जाता है जब आप इसे वापस पढ़ें:

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

आप एक स्ट्रिंग से एक पथ वस्तु बना सकते हैं।

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

तो, आंतरिक रूप से कॉमन लिस्प पथ नाम वस्तुओं के साथ काम करता है, लेकिन यह आप सामान्य तार का उपयोग करने देता है और यदि आवश्यक हो तो उन लोगों से पथ नाम वस्तुओं बनाता है।

कॉमन लिस्प एक पथ नाम (उदाहरण के निर्देशिका याद आ रही है के लिए) घटक निर्दिष्ट नहीं सब है कि देखता है, तो यह variabel * डिफ़ॉल्ट-पथ नाम-चूक का मूल्य है कि * पथ वस्तु से घटकों में भरता है।

समारोह के साथ

वर्णन आप एक पथ नाम (यहाँ Clozure सीएल) के घटक देखते कर सकते हैं: का उपयोग कर लिस्प कार्यों बनाने पथ नाम वस्तुओं

मेकअप पथ नाम

? (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 :name "foo" :defaults (pathname "/Users/bar/baz.text")) 
    

    आप निर्देशिका का उपयोग अगर यह वाइल्डकार्ड के साथ एक पथ नाम का उपयोग करने के लिए उपयोगी है। निर्देशिका तब मिलान पथनामों की एक सूची वापस कर देगा। 'डायरेक्टरी' नाम थोड़ा भ्रामक है, क्योंकि निर्देशिका निर्देशिका की सामग्री सूचीबद्ध नहीं करती है, लेकिन जंगलीकार्ड वाले पथनाम (आमतौर पर) के लिए मिलान करने वाले पथनाम सूचीबद्ध करती है। वाइल्डकार्ड /foo/s*c/list*.l* जैसे घटकों में वर्णों के अनुक्रमों से मेल खा सकते हैं। "वाइल्ड कार्ड ** भी है, जिसका उपयोग डायरेक्टरी जैसे भागों/foo/** के हिस्सों से मेल खाने के लिए किया जाता है। /test.lisp है, जो सभी फाइलों निर्देशिका foo और उसकी उप-के तहत test.lisp मेल खाता है।

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

    से ऊपर '/ उपयोगकर्ताओं/foo/लिस्प /' और सब में 'तुतलाना' फ़ाइलों की एक सूची वापस आ जाएगी उसकी उप-

    एक एकल निर्देशिका उपयोग में ग फ़ाइलों लौटने के लिए:।

    (directory "/Users/foo/c/src/*.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.* से मेल खाते हैं।

    इस रूप में ही है:

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

    जो कम है, लेकिन यूनिक्स पथ नाम वाक्य रचना पर निर्भर करता है।

+0

+1 LISP में पथनामों का एक अच्छा सारांश है, बहुत उपयोगी है। – Justicle

8

आधुनिक सामान्य लिस्प लाइब्रेरी निर्देशिका सूची लागू करने 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") 

ध्यान दें कि कोई स्लैश या वाइल्डकार्ड आवश्यक हैं। यह बहुत मजबूत है और गलत तरीके से एन्कोड किए गए यूनिकोड वर्णों के साथ फ़ाइल नामों को भी संसाधित कर सकता है।

मतभेद सीएल-एफएडी की तुलना में:

  • वस्तुओं आप प्राप्त IOLIB फ़ाइल पथ, सीएल के pathnames के लिए एक स्थानापन्न जो करीब क्या अंतर्निहित ओएस करता है।
  • आईओएलआईबी सीएफएफआई का उपयोग करके अपने दिनचर्या लागू करता है, इसलिए यह सीएल-एफएडी के विपरीत सभी लिस्प कार्यान्वयन (आईओएलआईबी ऑपरेटिंग सिस्टम के लिए बैकएंड है) पर भी काम करता है, जो कार्यान्वयन के डायरेक्ट्री फ़ंक्शन पर इसके सभी के साथ सारणी करने की कोशिश करता है quirks।
  • सीएल-एफएडी के विपरीत, आईओएलआईबी सिम्लिंक के साथ सही ढंग से काम करता है (सीएल-एफएडी के साथ एक बड़ा मुद्दा जो इसे विंडोज आईएमएचओ के अलावा प्लेटफ़ॉर्म पर लगभग अनुपयोगी बनाता है)।
1

मैं एक उदाहरण जोड़ूंगा जो कोड स्निपेट के लिए मेरे लिए काम करता है। मैं osicat (सीएल-फ़ैड के समान) और str का उपयोग करता हूं।

संपादित करें: uiop:directory-files के साथ भी। str: शामिल हैं? 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") 

यह निश्चित रूप से वाइल्डकार्ड के मेरे एक समुचित उपयोग सुधार किया जा सकता। हालांकि कि अभी एक टुकड़ा का उपयोग कर सकते है:)

संदर्भ: