रूबी में निर्देशिकाओं की पुनरावृत्ति करने के लिए वन-लाइनर?


96

रूबी में निर्देशिका (फ़ाइलों को छोड़कर) की एक सरणी प्राप्त करने का सबसे तेज़, सबसे अधिक अनुकूलित, एक-लाइनर तरीका क्या है?

फ़ाइलों सहित कैसे?


2
सबसे तेज, सबसे अधिक अनुकूलित और एक-लाइनर पठनीय / बनाए रखने के साथ बाधाओं पर हो सकता है। और, आप इसे एक बेंचमार्क और त्वरित परीक्षण का उपयोग करके पता लगा सकते हैं।
टीन मैन

जवाबों:


180
Dir.glob("**/*/") # for directories
Dir.glob("**/*") # for all files

इसके बजाय Dir.glob(foo)आप भी लिख सकते हैं Dir[foo](हालांकि Dir.globएक ब्लॉक भी ले सकते हैं, जिस स्थिति में यह एक सरणी बनाने के बजाय प्रत्येक पथ का उत्पादन करेगा)।

रूबी ग्लोब डॉक्स


10
का उपयोग करें Dir.glob("**/")जब तक आप भी सहानुभूति चाहते हैं
johannes

6
छिपी हुई फ़ाइलों और निर्देशिकाओं के बारे में क्या?
alediaferia

6
मैच परिणामों में डॉटफ़ाइल्स को शामिल करने के लिए, File::FNM_DOTMATCHध्वज का उपयोग करें ।
x-yuri

2
धन्यवाद @ x- यूरी! ध्वज btw इस तरह से निर्दिष्ट किया गया है:Dir.glob("**/*", File::FNM_DOTMATCH)
vlz

2
यहाँ प्रलेखन है: ruby-doc.org/core-2.2.0/Dir.html#method-c-glob
stephen.hanson

53

मेरा मानना ​​है कि यहां कोई भी समाधान छुपी हुई निर्देशिकाओं (जैसे '.test') से निपटता है:

require 'find'
Find.find('.') { |e| puts e if File.directory?(e) }

Find.find('/tmp').collect {|_|_}मेरे लिए सहायक था
अलेक्जेंडर बर्ड

Find के साथ सावधान रहें, यह symlinks का पालन नहीं करता है: stackoverflow.com/questions/3974087/…
leebutts

31

निर्देशिका की सूची के लिए प्रयास करें

Dir['**/']

फ़ाइलों की सूची कठिन है, क्योंकि यूनिक्स निर्देशिका में भी एक फ़ाइल है, इसलिए आपको टाइप करने के लिए परीक्षण करना होगा या लौटी हुई सूची से प्रविष्टियों को निकालना होगा जो अन्य प्रविष्टियों के माता-पिता हैं।

Dir['**/*'].reject {|fn| File.directory?(fn) }

और बस सभी फाइलों और निर्देशिकाओं की सूची के लिए

Dir['**/*']

ध्यान दें कि उन्होंने कहा "फाइलें भी शामिल हैं", "केवल फाइलें" नहीं, इसलिए आपको निर्देशिकाओं को हटाने की आवश्यकता नहीं है।
sepp2k

1
@ sepp2k हाँ, मैं इस भाग को याद करता था जब मैं irb के साथ खेल रहा था। लेकिन मैं इसे यहाँ छोड़ देता हूँ अगर कोई व्यक्ति कुछ इसी तरह की खोज कर सकता है :-)
MBO

7

तेज एक लाइनर

केवल निर्देशिका

`find -type d`.split("\n")

निर्देशिकाएँ और सामान्य फाइलें

`find -type d -or -type f`.split("\n")`

शुद्ध सुंदर माणिक

require "pathname"

def rec_path(path, file= false)
  puts path
  path.children.collect do |child|
    if file and child.file?
      child
    elsif child.directory?
      rec_path(child, file) + [child]
    end
  end.select { |x| x }.flatten(1)
end

# only directories
rec_path(Pathname.new(dir), false)
# directories and normal files
rec_path(Pathname.new(dir), true)

1
गलत: Dir.glob ("# {DIRECTORY} / ** / * /") मानचित्र। # निर्देशिका | Pathname.new (निर्देशिका)}
रॉबर्ट रॉस

क्या कोई end.select {}.flatten()हिस्सा समझा सकता है ? मुझे फंक्शन ओवरऑल पसंद है। ऐसा लगता है कि सरणियों की एक सरणी बनाएगा? क्या इसके elseifसाथ भाग करना संभव होगा : rec_path(child, file) << child.to_sताकि आप इसे एक सरणी में असाइन कर सकें और एक स्ट्रिंग प्राप्त कर सकें? धन्यवाद!
MCP

7

जैसा कि अन्य उत्तरों में यहां दिया गया है, आप उपयोग कर सकते हैं Dir.glob। ध्यान रखें कि फ़ोल्डरों में बहुत सारे अजीब चरित्र हो सकते हैं, और ग्लोब तर्क पैटर्न हैं, इसलिए कुछ पात्रों के विशेष अर्थ हैं। जैसे, यह निम्नलिखित की तरह कुछ करने के लिए असुरक्षित है:

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

इसके बजाय करें:

Dir.chdir(folder) { Dir.glob("**/*").map {|path| File.expand_path(path) } }

2

किसी निर्देशिका की सामग्री और उसकी सभी उपनिर्देशिकाओं को प्राप्त करने के लिए PHP या अन्य भाषाओं में, आपको कोड की कुछ पंक्तियाँ लिखनी होंगी, लेकिन रूबी में यह 2 पंक्तियाँ लेता है:

require 'find'
Find.find('./') do |f| p f end

यह वर्तमान निर्देशिका और इसकी सभी उपनिर्देशिकाओं की सामग्री को प्रिंट करेगा।

या छोटा, आप ’**’नोटेशन का उपयोग कर सकते हैं :

p Dir['**/*.*']

समान परिणाम प्राप्त करने के लिए आप PHP या जावा में कितनी लाइनें लिखेंगे?


13
स्रोत का हवाला दिए बिना mustap.com/rubyzone_post_162_recursive-directory-listing से सीधे कॉपी-पेस्ट करने के लिए डाउनवोट किया गया ...
एक्का

@kivetros मैंने लिंक का संग्रहीत संस्करण शामिल करने के लिए उत्तर संपादित किया :-)
एकबार्री

0

हालांकि एक पंक्ति समाधान नहीं है, मुझे लगता है कि यह रूबी कॉल का उपयोग करने का सबसे अच्छा तरीका है।

पहले सभी फ़ाइलों को पुनरावर्ती रूप से
हटा दें दूसरा सभी सभी खाली निर्देशिकाओं को हटा दें

Dir.glob("./logs/**/*").each { |file| File.delete(file) if File.file? file }
Dir.glob("./logs/**/*/").each { |directory| Dir.delete(directory) }

3
वह / वह फ़ाइलों / निर्देशिकाओं को हटाना नहीं चाहता है।
डेरेक नादेज़ा

एक पंक्ति में दोनों फ़ाइलों + निर्देशिका के लिए यह कैसे करें?
विपिन v१६

0

यहाँ एक उदाहरण दिया गया है जो कि Dir.glob के साथ रेल परियोजना निर्देशिका की गतिशील खोज को जोड़ती है:

dir = Dir.glob(Rails.root.join('app', 'assets', 'stylesheets', '*'))

मैंने यह कोशिश की >> config.assets.paths << Rails.root.join("app", "assets", "*"), लेकिन अभी भी सब-फोल्डर और एसेट फोल्डर के अंदर की फाइलेंRails.application.config.assets.paths
vipin8169

-1
Dir.open(Dir.pwd).map { |h| (File.file?(h) ? "#{h} - file" : "#{h} - folder") if h[0] != '.' }

डॉट्स शून्य वापस आते हैं, कॉम्पैक्ट का उपयोग करते हैं


1
यह बहुत सुंदर नहीं है, और ऐसा करने के लिए कुछ और लाइनों पर होने की आवश्यकता होगी
वनब्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.