একটি ডিরেক্টরিতে প্রতিটি ফাইলের মধ্যে Iterate


274

আমি রুবিতে কীভাবে একটি লুপ লিখব যাতে প্রতিটি ফাইলের কোডের একটি ব্লক কার্যকর করতে পারি?

আমি রুবিতে নতুন, এবং আমি উপসংহারে পৌঁছেছি যে এটি করার উপায়টি প্রতিটি লুপটি করা।
রুবি ফাইলটি যে ডিরেক্টরিটি লুপ করতে চাই তার চেয়ে আলাদা ডিরেক্টরি থেকে কার্যকর করা হবে।

আমি চেষ্টা করেছি Dir.foreachএবং আমি এটি কাজ করতে পারি না।


2
আপনি যখন এটি কার্যকর করার চেষ্টা করেছিলেন তখন কী ঘটতে পারে তা আপনি নির্দিষ্ট করতে পারেন? আপনি কোন সঠিক কোডটি ব্যবহার করেছেন (বা প্রাসঙ্গিক অংশটি যদি এটি দীর্ঘ হয়)? কোন ত্রুটি বার্তা পেয়েছেন? Dir.foreachএকটি ডিরেক্টরি সামগ্রীতে পুনরাবৃত্তি করতে কাজ করে, তাই অন্য কিছু হতে চলেছে।
টেলিমাচাস

3
আপনি যদি কেবল আপনার ডিরেক্টরিতে ফাইল চান তবে ডিরেক্টরি do_something_with(entry) if File.file?(entry)
সামগ্রীতে

3
'img/*.{jpg,png,gif,jpeg}'একাধিক এক্সটেনশান দখল করতে ব্যবহার করুন ।
বেনজামিন ক্রাউজিয়ার

দুর্ভাগ্যবশত, ক্রিসপিটারগুলি অসম্ভব বলে মনে হচ্ছে, কারণ চার বছরে ওপি সাইটে নেই the
জো কেনেডি

উত্তর:


429

অন্যরা Dir::foreachযেমন বলেছে, এখানে একটি ভাল বিকল্প। তবে, এটি নোট করুন Dir::foreachএবং Dir::entriesসর্বদা .এবং ..(বর্তমান এবং মূল ডিরেক্টরি) অন্তর্ভুক্ত থাকবে। আপনি এগুলিতে সাধারণত কাজ করতে চাইবেন না, তাই আপনি ব্যবহার করতে পারেন Dir::each_childবা Dir::children( ma11ee 28 দ্বারা প্রস্তাবিত ) বা এটির মতো কিছু করতে পারেন:

Dir.foreach('/path/to/dir') do |filename|
  next if filename == '.' or filename == '..'
  # Do work on the remaining files & directories
end

Dir::foreachএবং Dir::entries(সেইসাথে Dir::each_childএবং Dir::children) ও গোপন ফাইল & ডিরেক্টরি অন্তর্ভুক্ত। প্রায়শই এটি আপনি চান যা তবে এটি যদি না হয় তবে এগুলি এড়াতে আপনার কিছু করার প্রয়োজন do

বিকল্পভাবে, আপনি সন্ধান করতে চাইতে পারেন Dir::globযা কোন সহজ ওয়াইল্ডকার্ড মিলছে:

Dir.glob('/path/to/dir/*.rb') do |rb_filename|
  # Do work on files & directories ending in .rb
end

12
Dir.foreachডিরেক্টরিতে যদি বিপুল সংখ্যক ফাইল থাকে তবে ব্যবহার করুন !
টিলো

5
ধন্যবাদ! এটিকে আরও উন্নত করার জন্য ছোট মোড:next if File.directory? item
মিঃব্লটন

@ মিঃবাটনগুলি সর্বদা সঠিক কাজটি করে না। কখনও কখনও লোকেরা ফাইলের পাশাপাশি ডিরেক্টরিতেও কাজ করতে চায় । আমি বিশেষ তালিকা এড়ানোর জন্য কোড দিয়েছিলাম .বা ..লোকেরা প্রায়শই এই দুটিটিকে উপেক্ষা করতে চায়।
টেলিমাচাস

3
@ টিলো: মাত্র আগ্রহের বাইরে, আরও কিছুটা ব্যাখ্যা করার যত্ন কেন? :)
মকতাজা

11
@ এমকাতাজা পুনরায় Dir.foreachএকটি (সম্ভাব্য বিশাল) অ্যারের সামনে (যা Dir.globকরে) তৈরি করার পরিবর্তে পুনরাবৃত্তি করে। সুতরাং ডিরেক্টরি যদি সত্যিই বিশাল হয়, এটি একটি পারফরম্যান্সে পার্থক্য আনতে পারে। সাধারণ পরিস্থিতিতে আপনি লক্ষ্য করবেন না, কিন্তু চাপের পরিস্থিতিতে, এটি একেবারেই গুরুত্বপূর্ণ।
টেলিমাচাস

99

সহজেই পড়া সহজ হওয়ার জন্য এটি আমার প্রিয় পদ্ধতি:

Dir.glob("*/*.txt") do |my_text_file|
  puts "working on: #{my_text_file}..."
end

এবং আপনি এমনকি এটি সাবডিয়ার্সের সমস্ত ফাইলে কাজ করতে প্রসারিত করতে পারেন:

Dir.glob("**/*.txt") do |my_text_file| # note one extra "*"
  puts "working on: #{my_text_file}..."
end

30

ডিরেক্টরি থেকে সমস্ত ফাইলের একটি অ্যারে পেতে দিরের আরও ছোট সিনট্যাক্স রয়েছে:

Dir['dir/to/files/*'].each do |fname|
    # do something with fname
end

এই কোডটিতে কী ডিরেক্টরিগুলি fnameপুনরাবৃত্তির সাথে ব্যবহার করতে বাধা দেয় ?
kayleeFrye_onDeck


13

সন্ধান গ্রন্থাগারটি এই কাজের জন্য বিশেষভাবে ডিজাইন করা হয়েছে: https://ruby-doc.org/stdlib-2.5.1/libdoc/find/rdoc/Find.html

require 'find'
Find.find(path) do |file|
  # process
end

এটি একটি স্ট্যান্ডার্ড রুবি লাইব্রেরি, তাই এটি উপলব্ধ হওয়া উচিত


1
File.findযতবার সম্ভব তা পুনরুত্পূর্ণভাবে নেমে যায়, আপনি যেদিকেই যা দিন তা থেকে শুরু করে। আমি নিশ্চিত নই যে ওপি এটিই চায়।
টেলিমাচাস

আমি মনে করি না যে এই পদ্ধতিতে অ্যাক্সেস আছে - Find.find? আমার কি কোনও লাইব্রেরি ডাউনলোড করার দরকার আছে যা এই কার্যকারিতাটি অন্তর্ভুক্ত করে?
নীল-আকাশ

@ ব্যবহারকারী470184: "সন্ধান করুন" একটি মানক রুবি লাইব্রেরি এবং এটি ডিফল্ট রুবি ইনস্টলেশন সহ পাওয়া উচিত। তবে এটি ব্যবহার করার আগে আপনার "প্রয়োজনীয় 'সন্ধান করতে হবে"।
ফয়সাল

1
@Faisal পাবেনা আমি মত উল্লিখিত glob নিদর্শন পাস *.rbকরারfind()
Ashhar হাসান

7

আমি এটি পছন্দ করি, এটি উপরে বর্ণিত হয়নি।

require 'pathname'

Pathname.new('/my/dir').children.each do |path|
    puts path
end

সুবিধাটি হ'ল আপনি স্ট্রিংয়ের পরিবর্তে কোনও পাথনাম বস্তুটি পান, এটির সাহায্যে আপনি দরকারী জিনিসগুলি করতে পারেন এবং আরও এগিয়ে যেতে পারেন।


3
Dir.new('/my/dir').each do |name|
  ...
end

1
Dir.new ('/ আমার / dir') ছাড়াও Dir.entries ('/ আমার / dir') রয়েছে তবে Dir.forach () কিছুটা বেশি সংক্ষিপ্তসার।
টিন ম্যান

5
একবারে পুরো অ্যারে তৈরি করার Dir.foreachসময় @ZED পুনরাবৃত্তি Dir.entriesহয়। সুতরাং ডিরেক্টরি যদি অপরিসীম হয়, এটি একটি মেমরি হিট কম। (সাধারণত কোনও বড় ব্যাপার নয়, সম্ভবত, তবে এখনও ...)
টেলিম্যাকাস

2

.& এড়িয়ে যেতে .., আপনি ব্যবহার করতে পারেন Dir::each_child

Dir.each_child('/path/to/dir') do |filename|
  puts filename
end

Dir::children ফাইলের নামের একটি অ্যারে প্রদান করে।

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