2010-08-17 9 views
56

मैं किसी दिए गए फ़ोल्डर में किसी दिए गए प्रकार (कहें .pdf) की सभी फ़ाइलों को खोजने की कोशिश कर रहा हूं और उन्हें एक नए फ़ोल्डर में कॉपी कर रहा हूं। मुझे ऐसा करने में सक्षम होना जरूरी है कि रूट फ़ोल्डर निर्दिष्ट करें और उस फ़ोल्डर और उसके सभी सबफ़ोल्डर के माध्यम से दिए गए प्रकार (.pdf) से मेल खाने वाली किसी भी फाइल के लिए खोजें। क्या कोई मुझे रूट फ़ोल्डर के उपफोल्डर्स और उनके उपफोल्डर्स के माध्यम से खोजना चाहिए, इस पर मुझे एक हाथ दे सकता है। ऐसा लगता है कि एक रिकर्सिव विधि यहां चाल करेगी, लेकिन मैं एक सही तरीके से लागू नहीं कर सकता? (मैं इस कार्यक्रम को रास्ते में रूबी में लागू कर रहा हूं)।एक निश्चित प्रकार की फ़ाइलों के लिए फ़ोल्डर और उसके सभी उपफोल्डर्स को खोजना

उत्तर

54

आप Find मॉड्यूल चाहते हैं। Find.find एक पथ युक्त एक स्ट्रिंग लेता है, और प्रत्येक फ़ाइल के पथ के साथ पैरेंट पथ और उप-निर्देशिका को एक साथ ब्लॉक में पास कर देगा। कुछ उदाहरण कोड:

require 'find' 

pdf_file_paths = [] 
Find.find('path/to/search') do |path| 
    pdf_file_paths << path if path =~ /.*\.pdf$/ 
end 

कि रिकर्सिवली एक रास्ता खोज करेंगे, और सभी फ़ाइल नाम एक सरणी में .pdf में समाप्त होने वाले की दुकान।

79

इस प्रयास करें:

Dir.glob("#{folder}/**/*.pdf") 

जो

Dir["#{folder}/**/*.pdf"] 

कहाँ फ़ोल्डर चर आप के माध्यम से खोज करना चाहते हैं रूट फ़ोल्डर के लिए पथ है के समान है।

+0

दृष्टिकोण का उपयोग करना सही है, लेकिन कार्यान्वयन गलत है। इसे Dir.glob ('**/*। Pdf') – jergason

+2

होना चाहिए मुझे लगता है कि ओपी रिकर्सिव चाहता था, है ना? – rogerdpack

+0

मूल उत्तर (rogerdpack) ने मेरे लिए काम किया, लेकिन जेरगसन ने नहीं किया, मुझे डर है। – Joyce

9

ऊपर Jergason और मैट का जवाब करने के लिए एक छोटा सा सुधार के रूप में, इस तरीके से एक ही पंक्ति को गाढ़ा कर सकते हैं:

pdf_file_paths = Find.find('path/to/search').select { |p| /.*\.pdf$/ =~ p } 

इस रूप में ऊपर ढूँढें विधि का उपयोग करता है, लेकिन तथ्य यह है कि परिणाम एक गणनीय है का लाभ उठाता है (और इस तरह हम चयन का उपयोग कर सकते हैं) मैचों के सेट के साथ एक सरणी वापस पाने के लिए

16

यदि गति चिंता का विषय है, तो Dir.globFind.find से अधिक पसंद करें।

Warming up -------------------------------------- 
      Find.find 124.000 i/100ms 
      Dir.glob 515.000 i/100ms 
Calculating ------------------------------------- 
      Find.find  1.242k (± 4.7%) i/s -  6.200k in 5.001398s 
      Dir.glob  5.249k (± 4.5%) i/s -  26.265k in 5.014632s 

Comparison: 
      Dir.glob:  5248.5 i/s 
      Find.find:  1242.4 i/s - 4.22x slower 

 

require 'find' 
require 'benchmark/ips' 

dir = '.' 

Benchmark.ips do |x| 
    x.report 'Find.find' do 
    Find.find(dir).select { |f| f =~ /\*\.pdf/ } 
    end 

    x.report 'Dir.glob' do 
    Dir.glob("#{dir}/**/*\.pdf") 
    end 

    x.compare! 
end 

ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin15]

+2

पद के लिए धन्यवाद। शुरुआती लोगों के लिए यह जानना बहुत उपयोगी है कि मैं 'Dir.glob' बनाम' Find.find' के बीच किस विधि का उपयोग करूँ। – itsh

+2

इस मामले में धीमे होना चाहिए क्योंकि आप रेगेक्स के साथ मिल रहे हैं। दूसरी तरफ Dir.glob, रेगेक्स के रूप में उतना शक्तिशाली नहीं है, इसलिए मैं इसे तेज होने की उम्मीद करता हूं। – hirowatari

संबंधित मुद्दे

 संबंधित मुद्दे