使用 Ruby 从文件夹中获取所有文件的名称

发布于 2024-08-11 19:41:26 字数 30 浏览 3 评论 0原文

我想使用 Ruby 从文件夹中获取所有文件名。

I want to get all file names from a folder using Ruby.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

野生奥特曼 2024-08-18 19:41:26

您还可以使用 和 的快捷方式选项:

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

如果您想查找任何文件夹或子文件夹中的所有 Ruby 文件,

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

You also have the shortcut option of

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

and if you want to find all Ruby files in any folder or sub-folder:

Dir["/path/to/search/**/*.rb"]
暮凉 2024-08-18 19:41:26
Dir.entries(folder)

示例:

Dir.entries(".")

来源:http://ruby-doc.org/core /classes/Dir.html#method-c-entries

Dir.entries(folder)

example:

Dir.entries(".")

Source: http://ruby-doc.org/core/classes/Dir.html#method-c-entries

凉月流沐 2024-08-18 19:41:26

以下代码片段准确显示了目录内文件的名称,跳过子目录和 ".", ".." 点状文件夹:

Dir.entries("your/folder").select { |f| File.file? File.join("your/folder", f) }

The following snippets exactly shows the name of the files inside a directory, skipping subdirectories and ".", ".." dotted folders:

Dir.entries("your/folder").select { |f| File.file? File.join("your/folder", f) }
久而酒知 2024-08-18 19:41:26

要递归地获取所有文件(严格来说仅限文件):

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

或者任何不是目录的文件(File.file? 将拒绝非常规文件):

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

替代解决方案

使用 Find#find 结束像 Dir.glob 这样基于模式的查找方法实际上更好。请参阅此答案“单行递归列出目录”在 Ruby 中?”

To get all files (strictly files only) recursively:

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

Or anything that's not a directory (File.file? would reject non-regular files):

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

Alternative Solution

Using Find#find over a pattern-based lookup method like Dir.glob is actually better. See this answer to "One-liner to Recursively List Directories in Ruby?".

暗喜 2024-08-18 19:41:26

在 Ruby 2.5 中,您现在可以使用 Dir.children。它以数组形式获取除“.”之外的文件名。和“..”

示例:

Dir.children("testdir")   #=> ["config.h", "main.rb"]

http://ruby- doc.org/core-2.5.0/Dir.html#method-c-children

In Ruby 2.5 you can now use Dir.children. It gets filenames as an array except for "." and ".."

Example:

Dir.children("testdir")   #=> ["config.h", "main.rb"]

http://ruby-doc.org/core-2.5.0/Dir.html#method-c-children

败给现实 2024-08-18 19:41:26

这对我有用:

如果您不想要隐藏文件[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] UNIX 上的 .dotfile,我不知道 Windows 上的

This works for me:

If you don't want hidden files[1], use 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 }

Now, Dir.entries will return hidden files, and you don't need the wildcard asterix (you can just pass the variable with the directory name), but it will return the basename directly, so the File.xxx functions won't work.

# 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 on unix, I don't know about Windows

ˇ宁静的妩媚 2024-08-18 19:41:26

此代码仅返回带有扩展名的文件名(没有全局路径)

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

=> [文件_1.rb、文件_2.html、文件_3.js]

this code returns only filenames with their extension (without a global path)

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

=> [file_1.rb, file_2.html, file_3.js]

梦毁影碎の 2024-08-18 19:41:26

就我个人而言,我发现这对于循环文件夹中的文件最有用,具有前瞻性的安全性:

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

Personally, I found this the most useful for looping over files in a folder, forward looking safety:

Dir['/etc/path/*'].each do |file_name|
  next if File.directory? file_name 
end
半衬遮猫 2024-08-18 19:41:26

这是在目录中查找文件的解决方案:

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

This is a solution to find files in a directory:

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
我们只是彼此的过ke 2024-08-18 19:41:26

在获取目录中的所有文件名时,此代码段可用于拒绝目录 [...] 和以 开头的隐藏文件。

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

While getting all the file names in a directory, this snippet can be used to reject both directories [., ..] and hidden files which start with a .

files = Dir.entries("your/folder").reject {|f| File.directory?(f) || f[0].include?('.')}
巴黎夜雨 2024-08-18 19:41:26

这对我有用:

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

Dir.entries 返回一个字符串数组。然后,我们必须向 File.file? 提供文件的完整路径,除非 dir 等于我们当前的工作目录。这就是这个 File.join() 的原因。

This is what works for me:

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

Dir.entries returns an array of strings. Then, we have to provide a full path of the file to File.file?, unless dir is equal to our current working directory. That's why this File.join().

白首有我共你 2024-08-18 19:41:26
Dir.new('/home/user/foldername').each { |file| puts file }
Dir.new('/home/user/foldername').each { |file| puts file }
愚人国度 2024-08-18 19:41:26

一种简单的方法可能是:

dir = './' # desired directory
files = Dir.glob(File.join(dir, '**', '*')).select{|file| File.file?(file)}

files.each do |f|
    puts f
end

One simple way could be:

dir = './' # desired directory
files = Dir.glob(File.join(dir, '**', '*')).select{|file| File.file?(file)}

files.each do |f|
    puts f
end
孤千羽 2024-08-18 19:41:26

您可能还想使用 Rake::FileList (前提是您有 rake 依赖项):

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

根据 API:

文件列表是惰性的。当给出可能的全局模式列表时
将文件包含在文件列表中,而不是搜索文件
用于查找文件的结构,FileList 保存后者的模式
使用。

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

You may also want to use Rake::FileList (provided you have rake dependency):

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

According to the API:

FileLists are lazy. When given a list of glob patterns for possible
files to be included in the file list, instead of searching the file
structures to find the files, a FileList holds the pattern for latter
use.

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

携君以终年 2024-08-18 19:41:26

除了本线程中的建议之外,我想提一下,如果您还需要返回点文件(.gitignore 等),则使用 Dir.glob 您需要包含一个标志,如下所示:
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 最终花费了更长的时间,但即使没有,它仍然比递归情况下的其他选项。这一切都是在 OSX 上使用 ruby​​ 2.5.1。

In addition to the suggestions in this thread, I wanted to mention that if you need to return dot files as well (.gitignore, etc), with Dir.glob you would need to include a flag as so:
Dir.glob("/path/to/dir/*", File::FNM_DOTMATCH)
By default, Dir.entries includes dot files, as well as current a parent directories.

For anyone interested, I was curious how the answers here compared to each other in execution time, here was the results against deeply nested hierarchy. The first three results are non-recursive:

       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)

These were generated with the following benchmarking script:

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

The differences in file counts are due to Dir.entries including hidden files by default. Dir.entries ended up taking a bit longer in this case due to needing to rebuild the absolute path of the file to determine if a file was a directory, but even without that it was still taking consistently longer than the other options in the recursive case. This was all using ruby 2.5.1 on OSX.

又爬满兰若 2024-08-18 19:41:26

当加载操作目录中的所有文件名时,您可以使用

Dir.glob("*)

这将返回应用程序正在运行的上下文中的所有文件(注意,对于 Rails,这是顶层应用程序的目录)

您可以在此处进行其他匹配和递归搜索 https://ruby-doc.org/core-2.7.1/Dir.html#method-c-glob

When loading all names of files in the operating directory you can use

Dir.glob("*)

This will return all files within the context that the application is running in (Note for Rails this is the top level directory of the application)

You can do additional matching and recursive searching found here https://ruby-doc.org/core-2.7.1/Dir.html#method-c-glob

凶凌 2024-08-18 19:41:26
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

返回目录和所有子目录中文件的相对路径

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

returns file's relative paths from directory and all subdirectories

标点 2024-08-18 19:41:26

如果您想获取文件名数组包括符号链接,请使用

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

or Even

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')递归地。

If you want get an array of filenames including symlinks, use

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

or even

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

and if you want to go without symlinks, use

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

As shown in other answers, use Dir.glob('/path/to/dir/**/*') instead of Dir.new('/path/to/dir') if you want to get all the files recursively.

染火枫林 2024-08-18 19:41:26

如果您创建带有空格的目录:

mkdir "a b"
touch "a b/c"

您不需要转义目录名称,它会自动执行:

p Dir["a b/*"] # => ["a b/c"]

if you create directories with spaces:

mkdir "a b"
touch "a b/c"

You don't need to escape the directory names, it will do it automatically:

p Dir["a b/*"] # => ["a b/c"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文