Wie erstelle ich rekursiv Verzeichnisse in Ruby?

101

Ich möchte eine Datei als /a/b/c/d.txt speichern, weiß jedoch nicht, ob eines dieser Verzeichnisse vorhanden ist, und muss sie gegebenenfalls rekursiv erstellen. Wie kann man das in Rubin machen?

Jan.
quelle

Antworten:

197

Verwendung mkdir_p:

FileUtils.mkdir_p '/a/b/c'

Das _pist ein Unix - Überbleibsel für Eltern / Pfad , den Sie auch den Alias verwenden können , mkpathwenn diese mehr Sinn macht für Sie.

FileUtils.mkpath '/a/b/c'

In Ruby 1.9 wurde FileUtils aus dem Kern entfernt, daher müssen Sie require 'fileutils'.

Harmon Wood
quelle
9
+1. FileUtilsund Pathnamesind wahrscheinlich die wichtigsten Werkzeuge für Ruby-Shell-Scripting.
Jörg W Mittag
21

Verwenden Sie mkdir_p, um ein Verzeichnis rekursiv zu erstellen

path = "/tmp/a/b/c"

FileUtils.mkdir_p(path) unless File.exists?(path)
ferbass
quelle
5

Wenn Sie auf unixy-Computern ausgeführt werden, vergessen Sie nicht, dass Sie einen Shell-Befehl immer unter Ruby ausführen können, indem Sie ihn in Backticks platzieren.

`mkdir -p /a/b/c`
Matthew Schinckel
quelle
So positiv zu sein ist jedoch.
Matthew Schinckel
1
Das Einfügen eines Systembefehls in einen Unterprozess ist nicht die beste Idee. Es ist besser, es mit der Ruby-Standardbibliothek zu tun, um Fehler zu behandeln, das Ergebnis zu überprüfen usw.
noraj
2

Pfadname zur Rettung!

Pathname('/a/b/c/d.txt').dirname.mkpath
Vadym Tyemirov
quelle
Dies ist weniger intuitiv als die akzeptierte Antwort. Auch das Dokument für die Methode weiterleiten an FileUtils ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/…
noraj
Die Frage lautet: "Ich möchte eine Datei als /a/b/c/d.txt speichern, weiß aber nicht, ob eines dieser Verzeichnisse vorhanden ist." Meine Lösung ermöglicht es, den vorhandenen Dateipfad ('/a/b/c/d.txt') zu verwenden und ohne separate Analyse alle Ordner zu erstellen.
Vadym Tyemirov
Du meinst das dies erlaubt FileUtils.mkdir_p '/a/b/c'+ gleichzeitig zu erstellen d.txt?
Noraj
Nein, stattdessen erlaubt es Pathname('/a/b/c/d.txt').dirname.mkpathund File.write('/a/b/c/d.txt', content)ohne filename = '/a/b/c/d.txt'.rpartition('/').lastund den Rest der Analyse
Vadym Tyemirov
0

Sie können auch Ihre eigene Logik verwenden

def self.create_dir_if_not_exists(path)
  recursive = path.split('/')
  directory = ''
  recursive.each do |sub_directory|
    directory += sub_directory + '/'
    Dir.mkdir(directory) unless (File.directory? directory)
  end
end

Wenn also der Pfad 'tmp / a / b / c' ist, wenn 'tmp' nicht existiert, wird 'tmp' erstellt, dann 'tmp / a /' und so weiter und so fort.

Kamal Patwa
quelle
Man würde es vermeiden, das Rad neu zu erfinden.
Noraj