রুবি সহ একটি ফোল্ডার থেকে সমস্ত ফাইলের নাম পান


উত্তর:


537

আপনার শর্টকাট বিকল্পও রয়েছে

Dir["/path/to/search/*"]

এবং আপনি যদি কোনও ফোল্ডার বা উপ-ফোল্ডারে সমস্ত রুবি ফাইলগুলি সন্ধান করতে চান:

Dir["/path/to/search/**/*.rb"]

5
অথবা আপনি দির :: গ্লোব ()
ইয়োন লে লেচে

2
এছাড়াও, এর ./...পরিবর্তে ব্যবহার করুন~/
মিনহ ট্রিয়েট

5
কেন এই পছন্দ?
BvuRVKyUVlViVIc7

1
@ মিনিট্রিট এটি কী করে? এটা কি ভাল?
স্টেফেনমুরডাক

9
@মারফ্লার - ./মানে বর্তমান ডিরেক্টরি, যেখানে /মূল রুট মাউন্ট পয়েন্ট এবং ~/এটি ব্যবহারকারীর হোম ডিরেক্টরি। আপনি যদি পুরো প্রকল্পটি অন্য কোথাও সরান, প্রথমটি কাজ করবে তবে অন্য দুটি সম্ভবত তা করবে না।
মরিচান

170
Dir.entries(folder)

উদাহরণ:

Dir.entries(".")

সূত্র: http://ruby-doc.org/core/classes/Dir.html#method-c-entries


15
দেখে মনে হচ্ছে যে তিনি সদ্য জিজ্ঞাসা করা প্রশ্নের উত্তরগুলি নথির জন্য এসও ব্যবহার করছেন। আমি মনে করি এক প্রকার মেমো। এর সাথে খুব বেশি ভুল দেখতে পাচ্ছে না - সর্বোপরি, যদিও এইটি কিছুটা অসম্পূর্ণ ( Dir#globসম্ভবত উল্লেখ করা যেতে পারে) সত্যিই ভাল উত্তর পোস্ট করা থেকে অন্য কাউকে রোধ করার মতো কিছুই নেই। 'অবশ্যই, আমি বেশিরভাগ লোকের মতো "গ্লাস অর্ধ পূর্ণ" ধরণের ...
মাইক উডহাউস

1
@ মাইক: জিনিসগুলির দুর্দান্ত পরিকল্পনায় এটি সম্ভবত কোনও বড় বিষয় নয়। এবং আপনি যেমনটি বলছেন যদি প্রশ্নোত্তরগুলি ভাল হয় তবে এটি সাইটের জন্য সামগ্রিক সামগ্রিক হতে পারে। তবে এখানে প্রশ্ন এবং উত্তর উভয়ই ন্যূনতম যে এটি বিশেষভাবে কার্যকর বলে মনে হচ্ছে না।
টেলিমাচাস

17
@ টেলিম্যাচাস আমি Dirখুব কমই ব্যবহার করি এবং যতবার দরকার হয় আমাকে ডকুমেন্টেশন পড়তে হয়। আমি আমার প্রশ্ন এবং উত্তর এখানে পোস্ট করেছি যাতে আমি এটি পরে খুঁজে পেতে পারি এবং এমনকি একই প্রশ্নে কাউকে সাহায্য করতে পারি। আমি মনে করি আমি এসও পডকাস্টে শুনেছি যে এই জাতীয় আচরণে কোনও ভুল নেই। আপনার আরও ভাল উত্তর থাকলে দয়া করে এটি পোস্ট করুন। আমি যা জানি তা পোস্ট করেছি, আমি রুবি নিনজা নই। আমি নিয়মিত সর্বাধিক ভোট দিয়ে উত্তর গ্রহণ করি।
jeljko ফিলিপিন

এই তুলনায় একটি ভালো বিকল্প হতে পারে Dir[]বা Dir.globযখন যুক্তি পরিবর্তনশীল। কখন path = '/tmp', তুলনা করুন: Dir.glob("#{path}/*")বনাম Dir.entries(path)। ফিরতি মানগুলি কিছুটা পৃথক ("।", "..") তবে পরবর্তীগুলি দ্রুত এক নজরে আঁকানো সহজ।
বেনজমিন ওকে

92

নিম্নলিখিত স্নিপেটগুলি হ'ল একটি ডিরেক্টরিতে থাকা ফাইলের নাম, উপ-ডিরেক্টরিগুলি এবং ".", ".."বিন্দুযুক্ত ফোল্ডারগুলি এড়িয়ে চলেছে :

Dir.entries("your/folder").select {|f| !File.directory? f}

19
...select {|f| File.file? f}পরিষ্কার অর্থ এবং সংক্ষিপ্ত সিনট্যাক্সের জন্যও করতে পারে ।
অটোম্যাটিকো

2
@ স্পুইসি আপনি কি এটি সঠিকভাবে লিখেছেন ?:Dir.entries("your/folder").select {|f| File.file? f}
অটোমেটিকো

9
হাঁ। !File.directory?কাজ করছে কিন্তু করছে File.file?না
কামিল লেলোনেক

2
@ সিকুইসি আমারও একই সমস্যা ছিল, আমার ক্ষেত্রে আমার কেবল ডায়ার ফায়ারচ ফাইলের নাম ফিরিয়ে দেওয়া নয় পুরো পথটি সরবরাহ করা দরকার
দ্য লুকুকামকার্তি

6
.reject {|f| File.directory? f}তুলনায় পরিষ্কার মনে হচ্ছে .select{|f| !File.directory? f}। ওহ, এবং এখন আমি প্রথম মন্তব্যটি দেখতে পাচ্ছি ... ভাল।
ইয়ান

36

সমস্ত ফাইল (কেবলমাত্র কঠোরভাবে ফাইলগুলি) পুনরাবৃত্তভাবে পেতে:

Dir.glob('path/**/*').select{ |e| File.file? e }

বা যে কোনও ডিরেক্টরি যা ডিরেক্টরি নয় ( File.file?নিয়মিত ফাইলগুলি বাতিল করবে):

Dir.glob('path/**/*').reject{ |e| File.directory? e }

বিকল্প সমাধান

ব্যবহার Find#findএকটি প্যাটার্ন-ভিত্তিক লুকআপ পদ্ধতি উপর মত Dir.globআসলে উত্তম। "রুবিতে পুনরাবৃত্তভাবে ডিরেক্টরি তালিকাভুক্ত করার জন্য ওয়ান-লাইনারের এই উত্তরটি দেখুন ?"


18

এটি আমার পক্ষে কাজ করে:

আপনি যদি লুকানো ফাইলগুলি না চান [1], দির ব্যবহার করুন [] :

# With a relative path, Dir[] will return relative paths 
# as `[ './myfile', ... ]`
#
Dir[ './*' ].select{ |f| File.file? f } 

# Want just the filename?
# as: [ 'myfile', ... ]
#
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.basename f }

# Turn them into absolute paths?
# [ '/path/to/myfile', ... ]
#
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.absolute_path f }

# With an absolute path, Dir[] will return absolute paths:
# as: [ '/home/../home/test/myfile', ... ]
#
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }

# Need the paths to be canonical?
# as: [ '/home/test/myfile', ... ]
#
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }.map{ |f| File.expand_path f }

এখন, ডি.আরন্ট্রিগুলি লুকানো ফাইলগুলি ফিরিয়ে দেবে, এবং আপনার ওয়াইল্ডকার্ড অ্যাসেরিক্সের প্রয়োজন হবে না (আপনি কেবল ডিরেক্টরি নামের সাথে ভেরিয়েবলটি পাস করতে পারেন) তবে এটি সরাসরি বেস নামটি ফিরিয়ে দেবে, সুতরাং ফাইল.এক্সএক্সএক্সএক্স ফাংশনগুলি কাজ করবে না ।

# In the current working dir:
#
Dir.entries( '.' ).select{ |f| File.file? f }

# In another directory, relative or otherwise, you need to transform the path 
# so it is either absolute, or relative to the current working dir to call File.xxx functions:
#
home = "/home/test"
Dir.entries( home ).select{ |f| File.file? File.join( home, f ) }

[1] .dotfileইউনিক্সে, আমি উইন্ডোজ সম্পর্কে জানি না



9

ব্যক্তিগতভাবে, আমি ফোল্ডারে ফাইলগুলি লুপিংয়ের জন্য, সুরক্ষার সন্ধানের জন্য এটি সবচেয়ে দরকারী বলে মনে করেছি:

Dir['/etc/path/*'].each do |file_name|
  next if File.directory? file_name 
end

9

এটি একটি ডিরেক্টরিতে ফাইলগুলি সন্ধান করার একটি সমাধান:

files = Dir["/work/myfolder/**/*.txt"]

files.each do |file_name|
  if !File.directory? file_name
    puts file_name
    File.open(file_name) do |file|
      file.each_line do |line|
        if line =~ /banco1/
          puts "Found: #{line}"
        end
      end
    end
  end
end

6

ডিরেক্টরিতে সমস্ত ফাইলের নাম পাওয়ার পরে, এই স্নিপেটটি ডিরেক্টরি [ ., ..] এবং লুকানো ফাইল উভয়ই প্রত্যাখ্যান করতে ব্যবহার করা যেতে পারে যা একটি দিয়ে শুরু হয়.

files = Dir.entries("your/folder").reject {|f| File.directory?(f) || f[0].include?('.')}

Dir.entriesস্থানীয় ফাইলের নাম ফেরত দেয়, সম্পূর্ণ ফাইলের পথ নয়। অন্যদিকে, File.directory?একটি নিখুঁত ফাইল পাথ আশা করে। এই কোডটি প্রত্যাশার মতো কাজ করে না।
নাথান

এটি অদ্ভুত কোডটি আপনার ক্ষেত্রে কাজ করে না। এটি একটি কোড হিসাবে আমি একটি লাইভ অ্যাপ্লিকেশন ব্যবহার করেছি যা ঠিক কাজ করে। আমি আমার কোডটি যাচাই করে নেব এবং আমার আসল ওয়ার্কিং কোড থেকে কিছু অনুপস্থিত থাকলে এখানে পোস্ট করব :)
লাহিরু

1
@ নাথান আমার ব্যাখ্যার জন্য উত্তরটি দেখুন

5

এই কোডটি কেবল তাদের এক্সটেনশন সহ ফাইলের নামগুলি দেয় (বিশ্বব্যাপী পাথ ব্যতীত)

Dir.children("/path/to/search/")

4

এটি আমার জন্য কাজ করে কি:

Dir.entries(dir).select { |f| File.file?(File.join(dir, f)) }

Dir.entriesস্ট্রিংগুলির একটি অ্যারের প্রদান করে। এর পরে, আমরা ফাইল একটি পূর্ণ পাথ প্রদান করতে হবে File.file?, যদি না dirআমাদের সাম্প্রতিক কাজ করা সমান। এই কারণেই File.join()


1
আপনাকে "বাদ দিতে হবে"। এবং এন্ট্রি থেকে ".."
এডগার অরতেগা

3

আপনি ব্যবহার করতে পারেন Rake::FileList(আপনি যদি rakeনির্ভরতা পান তবে):

FileList.new('lib/*') do |file|
  p file
end

এপিআই অনুসারে:

ফাইললিস্টগুলি অলস। ফাইল তালিকাতে অন্তর্ভুক্ত করার জন্য সম্ভাব্য ফাইলগুলির জন্য গ্লোব প্যাটার্নগুলির একটি তালিকা দেওয়া হলে ফাইলগুলি অনুসন্ধান করার জন্য ফাইলের কাঠামোগুলি অনুসন্ধান করার পরিবর্তে, একটি ফাইললিস্ট পরে ব্যবহারের জন্য প্যাটার্ন ধারণ করে।

https://docs.ruby-lang.org/en/2.1.0/Rake/FileList.html


1

আপনি যদি সিমলিংক সহ ফাইলের নামের একটি অ্যারে পেতে চান তবে ব্যবহার করুন

Dir.new('/path/to/dir').entries.reject { |f| File.directory? f }

অথবা এমনকি

Dir.new('/path/to/dir').reject { |f| File.directory? f }

এবং আপনি যদি সিমলিংক ছাড়াই যেতে চান তবে ব্যবহার করুন

Dir.new('/path/to/dir').select { |f| File.file? f }

অন্যান্য উত্তরে যেমন দেখানো হয়েছে, আপনি সমস্ত ফাইল পুনরাবৃত্তভাবে পেতে চান তার Dir.glob('/path/to/dir/**/*')পরিবর্তে ব্যবহার করুন Dir.new('/path/to/dir')


বা কেবল ব্যবহার করুন*.*
রিচার্ড পেক


1

এই থ্রেডের পরামর্শ ছাড়াও, আমি উল্লেখ করতে চাইছিলাম যে আপনার যদি Dir.glob এর সাথে ডট ফাইলও (.gitignore, ইত্যাদি) ফেরত দরকার হয় তবে আপনাকে একটি পতাকাও অন্তর্ভুক্ত করতে হবে: Dir.glob("/path/to/dir/*", File::FNM_DOTMATCH) ডিফল্টরূপে, Dir.entries ডট ফাইলগুলি পাশাপাশি বর্তমানের পিতামাতাদের ডিরেক্টরি অন্তর্ভুক্ত করে।

আগ্রহী যে কারও জন্য, আমি কৌতূহল ছিলাম যে এখানে উত্তরগুলি কার্যকর করার সময় একে অপরের সাথে তুলনা করে, এখানে গভীরভাবে নেস্টেড শ্রেণিবিন্যাসের বিরুদ্ধে ফলাফল ছিল। প্রথম তিনটি ফলাফল পুনরাবৃত্তিযোগ্য:

       user     system      total        real
Dir[*]: (34900 files stepped over 100 iterations)
  0.110729   0.139060   0.249789 (  0.249961)
Dir.glob(*): (34900 files stepped over 100 iterations)
  0.112104   0.142498   0.254602 (  0.254902)
Dir.entries(): (35600 files stepped over 100 iterations)
  0.142441   0.149306   0.291747 (  0.291998)
Dir[**/*]: (2211600 files stepped over 100 iterations)
  9.399860  15.802976  25.202836 ( 25.250166)
Dir.glob(**/*): (2211600 files stepped over 100 iterations)
  9.335318  15.657782  24.993100 ( 25.006243)
Dir.entries() recursive walk: (2705500 files stepped over 100 iterations)
 14.653018  18.602017  33.255035 ( 33.268056)
Dir.glob(**/*, File::FNM_DOTMATCH): (2705500 files stepped over 100 iterations)
 12.178823  19.577409  31.756232 ( 31.767093)

এগুলি নিম্নোক্ত বেঞ্চমার্কিং স্ক্রিপ্টের সাহায্যে তৈরি করা হয়েছিল:

require 'benchmark'
base_dir = "/path/to/dir/"
n = 100
Benchmark.bm do |x|
  x.report("Dir[*]:") do
    i = 0
    n.times do
      i = i + Dir["#{base_dir}*"].select {|f| !File.directory? f}.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
  x.report("Dir.glob(*):") do
    i = 0
    n.times do
      i = i + Dir.glob("#{base_dir}/*").select {|f| !File.directory? f}.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
  x.report("Dir.entries():") do
    i = 0
    n.times do
      i = i + Dir.entries(base_dir).select {|f| !File.directory? File.join(base_dir, f)}.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
  x.report("Dir[**/*]:") do
    i = 0
    n.times do
      i = i + Dir["#{base_dir}**/*"].select {|f| !File.directory? f}.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
  x.report("Dir.glob(**/*):") do
    i = 0
    n.times do
      i = i + Dir.glob("#{base_dir}**/*").select {|f| !File.directory? f}.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
  x.report("Dir.entries() recursive walk:") do
    i = 0
    n.times do
      def walk_dir(dir, result)
        Dir.entries(dir).each do |file|
          next if file == ".." || file == "."

          path = File.join(dir, file)
          if Dir.exist?(path)
            walk_dir(path, result)
          else
            result << file
          end
        end
      end
      result = Array.new
      walk_dir(base_dir, result)
      i = i + result.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
  x.report("Dir.glob(**/*, File::FNM_DOTMATCH):") do
    i = 0
    n.times do
      i = i + Dir.glob("#{base_dir}**/*", File::FNM_DOTMATCH).select {|f| !File.directory? f}.length
    end
    puts " (#{i} files stepped over #{n} iterations)"
  end
end

ফাইল গণনায় পার্থক্য হ'ল Dir.entriesডিফল্টরূপে লুকানো ফাইল অন্তর্ভুক্ত। Dir.entriesকোনও ফাইল ডিরেক্টরি ছিল কিনা তা নির্ধারণ করার জন্য ফাইলটির পরম পাথটি পুনর্নির্মাণের প্রয়োজনের কারণে এই ক্ষেত্রে কিছুটা বেশি সময় নিয়ে শেষ হয়েছিল, তবে তা ছাড়া এটি পুনরাবৃত্তির ক্ষেত্রে অন্যান্য বিকল্পগুলির তুলনায় ধারাবাহিকভাবে আরও বেশি সময় নিচ্ছিল। এটি সমস্ত ওএসএক্সে রুবি 2.5.1 ব্যবহার করছিল।



0
def get_path_content(dir)
  queue = Queue.new
  result = []
  queue << dir
  until queue.empty?
    current = queue.pop
    Dir.entries(current).each { |file|
      full_name = File.join(current, file)
      if not (File.directory? full_name)
        result << full_name
      elsif file != '.' and file != '..'
          queue << full_name
      end
    }
  end
  result
end

ডিরেক্টরি এবং সমস্ত উপ-ডিরেক্টরি থেকে ফাইলের আপেক্ষিক পাথ ফেরত দেয়


0

আইআরবি প্রসঙ্গে আপনি বর্তমান ডিরেক্টরিতে ফাইলগুলি পেতে নিম্নলিখিতটি ব্যবহার করতে পারেন:

file_names = `ls`.split("\n")

আপনি অন্যান্য ডিরেক্টরিতেও এই কাজটি করতে পারেন:

file_names = `ls ~/Documents`.split("\n")

এই সমাধানগুলি আমার পক্ষে কাজ করেছে যেহেতু আমার কাছে পুরানো রুবি সংস্করণ সহ উত্তরাধিকার সমাধান রয়েছে যা দির.চিল্ডেন কমান্ড সমর্থন করে না
সিপরিয়ান ড্রাগো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.