回答:
次のショートカットオプションもあります
Dir["/path/to/search/*"]
また、任意のフォルダーまたはサブフォルダー内のすべてのRubyファイルを検索する場合:
Dir["/path/to/search/**/*.rb"]
./...
代わりに使用~/
./
現在のディレクトリを意味します/
が、これはルートマウントポイントであり~/
、ユーザーのホームディレクトリです。プロジェクト全体を別の場所に移動した場合、最初のプロジェクトは機能しますが、他の2つはおそらく機能しません。
Dir.entries(folder)
例:
Dir.entries(".")
出典:http : //ruby-doc.org/core/classes/Dir.html#method-c-entries
Dir#glob
見つけることはできません-結局のところ、これは少し不完全です(たとえば、おそらく言及されているかもしれません)が、他の誰かが本当に良い回答を投稿するのを妨げるものは何もありません。'もちろん、私はほとんど「グラスハーフフル」のような男です...
Dir
めったに使用せず、必要になるたびにドキュメントを読む必要があります。質問と回答をここに投稿しましたので、後で見つけたり、同じ質問で誰かを助けたりすることができます。私はSOポッドキャストでそのような振る舞いに何も問題はないと聞いたと思います。より良い答えがある場合は、投稿してください。私は知っていることを投稿しました。私はRuby忍者ではありません。投票数が最も多い回答を定期的に受け入れます。
Dir[]
か、Dir.glob
引数が変数であるとき。の場合path = '/tmp'
、比較: Dir.glob("#{path}/*")
対Dir.entries(path)
。戻り値は少し異なりますが( "。"、 "..")、後者は一目で理解するのが簡単です。
次のスニペットは、ディレクトリ内のファイルの名前を正確に示しており"."
、サブディレクトリと".."
ドット付きフォルダをスキップしています。
Dir.entries("your/folder").select {|f| !File.directory? f}
...select {|f| File.file? f}
より明確な意味とより短い構文のためにも行うことができます。
Dir.entries("your/folder").select {|f| File.file? f}
!File.directory?
機能してFile.file?
いますが機能していません。
.reject {|f| File.directory? f}
よりもきれいなようです.select{|f| !File.directory? f}
。ああ、今、最初のコメントが表示されます...いいですね。
すべてのファイル(厳密にはファイルのみ)を再帰的に取得するには:
Dir.glob('path/**/*').select{ |e| File.file? e }
またはディレクトリではないもの(File.file?
通常でないファイルは拒否されます):
Dir.glob('path/**/*').reject{ |e| File.directory? e }
のFind#find
ようなパターンベースのルックアップ方法を使用するDir.glob
方が実際には優れています。「Rubyでディレクトリを再帰的に一覧表示するための1行」という回答を参照してください。。
これは私にとってはうまくいきます:
隠しファイルが必要ない場合は、[1]、Dir []を使用します。
# 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 }
これで、Dir.entriesは隠しファイルを返し、ワイルドカードアスタリスクは必要ありません(変数をディレクトリ名で渡すことができます)が、ベース名を直接返すため、File.xxx関数は機能しません。 。
# 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
UNIXでは、Windowsについて知りません
Ruby 2.5ではを使用できるようになりましたDir.children
。「。」以外のファイル名を配列として取得します。そして「..」
例:
Dir.children("testdir") #=> ["config.h", "main.rb"]
個人的には、これはフォルダー内のファイルをループするのに最も便利で、前向きな安全性です。
Dir['/etc/path/*'].each do |file_name|
next if File.directory? file_name
end
ディレクトリ内のすべてのファイル名を取得している間、このスニペットを使用して、ディレクトリ[ .
、..
]と、.
files = Dir.entries("your/folder").reject {|f| File.directory?(f) || f[0].include?('.')}
Dir.entries
絶対ファイルパスではなく、ローカルファイル名を返します。一方、File.directory?
絶対ファイルパスが必要です。このコードは期待どおりに動作しません。
このコードは、拡張子を持つファイル名のみを返します(グローバルパスなし)
Dir.children("/path/to/search/")
Rake::FileList
(rake
依存関係がある場合)を使用することもできます。
FileList.new('lib/*') do |file|
p file
end
APIによると:
FileListは遅延します。ファイルリストに含まれる可能性のあるファイルのグロブパターンのリストが与えられると、ファイル構造を検索してファイルを見つける代わりに、FileListは後の使用のためにパターンを保持します。
symlinksを含むファイル名の配列を取得したい場合は、
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')
、代わりにを使用してください。
*.*
このスレッドでの提案に加えて、ドットファイル(.gitignoreなど)も返す必要がある場合は、Dir.globを使用してフラグを含める必要があることを述べておきます。
Dir.glob("/path/to/dir/*", File::FNM_DOTMATCH)
使用して、次のます。デフォルトでは、Dir.entries現在の親ディレクトリだけでなく、ドットファイルも含まれます。
興味のある方は、ここでの回答が実行時間で互いにどのように比較されるのかを知りました。深くネストされた階層に対する結果です。最初の3つの結果は非再帰的です。
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
この場合、ファイルがディレクトリであるかどうかを判断するためにファイルの絶対パスを再構築する必要があるため、少し時間がかかりましたが、それがなくても、再帰的な場合の他のオプションよりも一貫して時間がかかっていました。これはすべてOSXでruby 2.5.1を使用していました。
簡単な方法の1つは次のとおりです。
dir = './' # desired directory
files = Dir.glob(File.join(dir, '**', '*')).select{|file| File.file?(file)}
files.each do |f|
puts f
end
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
ディレクトリとすべてのサブディレクトリからファイルの相対パスを返します
IRBコンテキストでは、次を使用して現在のディレクトリ内のファイルを取得できます。
file_names = `ls`.split("\n")
これを他のディレクトリでも機能させることができます:
file_names = `ls ~/Documents`.split("\n")