it-swarm.com.de

Holen Sie sich die Namen aller Dateien aus einem Ordner mit Ruby

Ich möchte mit Ruby alle Dateinamen aus einem Ordner erhalten.

322
Željko Filipin

Sie haben auch die Verknüpfungsoption von

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

und wenn Sie alle Ruby Dateien in einem beliebigen Ordner oder Unterordner suchen möchten:

Dir["/path/to/search/**/*.rb"]
488
Ian Eccles
Dir.entries(folder)

beispiel:

Dir.entries(".")

Quelle: http://Ruby-doc.org/core/classes/Dir.html#method-c-entries

156
Željko Filipin

Die folgenden Ausschnitte zeigen genau den Namen der Dateien in einem Verzeichnis, überspringen Unterverzeichnisse und ".", ".." gepunktete Ordner:

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

So rufen Sie alle Dateien (ausschließlich Dateien) rekursiv ab:

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

Oder irgendetwas, das kein Verzeichnis ist (File.file? würde nicht reguläre Dateien ablehnen):

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

Alternative Lösung

Mit Find#find über eine musterbasierte Suchmethode wie Dir.glob ist eigentlich besser. Siehe diese Antwort auf "Einzeilig, um Verzeichnisse in Ruby rekursiv aufzulisten?" .

32
konsolebox

Das funktioniert bei mir:

Wenn Sie keine versteckten Dateien [1] möchten, verwenden Sie 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 }

Nun wird Dir.entries versteckte Dateien zurückgeben und Sie brauchen kein Platzhalter-Sternchen (Sie können nur die Variable mit dem Verzeichnisnamen übergeben), sondern es wird direkt der Basisname zurückgegeben, also die Datei .xxx-Funktionen funktionieren nicht.

# 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 Unter Unix kenne ich Windows nicht

14
user1115652

Persönlich fand ich dies am nützlichsten, um Dateien in einem Ordner in einer Schleife zu durchlaufen und die Sicherheit in die Zukunft zu lenken:

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

Dies ist eine Lösung, um Dateien in einem Verzeichnis zu finden:

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
8
gilcierweb

In Ruby 2.5 kannst du jetzt Dir.children. Es werden Dateinamen als Array mit Ausnahme von "." und ".."

Beispiel:

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

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

5
Mario Pérez

Während alle Dateinamen in einem Verzeichnis abgerufen werden, kann dieses Snippet verwendet werden, um sowohl Verzeichnisse [., ..] Als auch versteckte Dateien abzulehnen, die mit einem . Beginnen.

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

Das funktioniert bei mir:

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

Dir.entries Gibt ein Array von Zeichenfolgen zurück. Dann müssen wir einen vollständigen Pfad der Datei zu File.file? Angeben, es sei denn, dir entspricht unserem aktuellen Arbeitsverzeichnis. Deshalb ist diese File.join().

3
yegor256

Möglicherweise möchten Sie auch Rake::FileList (vorausgesetzt, Sie haben rake Abhängigkeit):

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

Nach der API:

FileLists sind faul. Wenn eine Liste von Glob-Mustern für mögliche Dateien in die Dateiliste aufgenommen wird, enthält eine Dateiliste das Muster für die spätere Verwendung, anstatt die Dateistrukturen zu durchsuchen, um die Dateien zu finden.

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

2
Artur Beljajev

Zusätzlich zu den Vorschlägen in diesem Thread wollte ich erwähnen, dass, wenn Sie auch Punktdateien (.gitignore usw.) zurückgeben müssen, Sie mit Dir.glob ein Flag wie folgt einfügen müssen: Dir.glob("/path/to/dir/*", File::FNM_DOTMATCH) Standardmäßig enthält Dir.entries Punktdateien sowie aktuelle übergeordnete Verzeichnisse.

Für alle Interessierten war ich gespannt, wie die Antworten hier in der Ausführungszeit miteinander verglichen wurden, hier waren die Ergebnisse gegen tief verschachtelte Hierarchien. Die ersten drei Ergebnisse sind nicht rekursiv:

       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)

Diese wurden mit folgendem Benchmarking-Skript generiert:

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

Die Unterschiede in der Anzahl der Dateien sind auf Dir.entries schließt standardmäßig versteckte Dateien ein. Dir.entries dauerte in diesem Fall etwas länger, da der absolute Pfad der Datei neu erstellt werden musste, um festzustellen, ob es sich bei einer Datei um ein Verzeichnis handelte. Selbst ohne diesen Pfad dauerte dies immer noch länger als die anderen Optionen im rekursiven Fall. Dies war alles mit Ruby 2.5.1 unter OSX.

1
Ben
Dir.new('/home/user/foldername').each { |file| puts file }
1
Ashwin

Wenn Sie eine Reihe von Dateinamen erhalten möchten einschließlich Symlinks, verwenden Sie

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

oder auch

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

und wenn du gehen willst ohne symlinks, benutze

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

Verwenden Sie, wie in anderen Antworten gezeigt, Dir.glob('/path/to/dir/**/*') anstelle von Dir.new('/path/to/dir'), wenn Sie alle Dateien rekursiv abrufen möchten.

1
Mikhail Vasin
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

gibt die relativen Pfade der Datei aus dem Verzeichnis und allen Unterverzeichnissen zurück

0
punksta

In einem IRB-Kontext können Sie Folgendes verwenden, um die Dateien im aktuellen Verzeichnis abzurufen:

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

Sie können dies auch für andere Verzeichnisse ausführen:

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

dieser Code gibt nur Dateinamen mit ihrer Erweiterung zurück (ohne globalen Pfad).

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

Ein einfacher Weg könnte sein:

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

files.each do |f|
    puts f
end
0