Comment créer des répertoires récursivement en ruby?

101

Je souhaite stocker un fichier sous le nom /a/b/c/d.txt, mais je ne sais pas si l'un de ces répertoires existe et je dois les créer récursivement si nécessaire. Comment faire ça en rubis?

Jan
la source

Réponses:

197

Utilisez mkdir_p:

FileUtils.mkdir_p '/a/b/c'

Il _ps'agit d'un maintien unix pour parent / chemin, vous pouvez également utiliser l'alias mkpathsi cela a plus de sens pour vous.

FileUtils.mkpath '/a/b/c'

Dans Ruby 1.9, FileUtils a été supprimé du noyau, vous devrez donc le faire require 'fileutils'.

Bois Harmon
la source
9
+1. FileUtilset Pathnamesont probablement les outils les plus importants pour la création de scripts Ruby shell.
Jörg W Mittag
21

Utilisez mkdir_p pour créer un répertoire de manière récursive

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

FileUtils.mkdir_p(path) unless File.exists?(path)
ferbasse
la source
5

Si vous utilisez des machines unixy, n'oubliez pas que vous pouvez toujours exécuter une commande shell sous ruby ​​en la plaçant dans des backticks.

`mkdir -p /a/b/c`
Matthew Schinckel
la source
Être si positif est cependant.
Matthew Schinckel
1
Faire apparaître la commande système dans le sous-processus n'est pas la meilleure idée. Il est préférable de le faire avec la bibliothèque standard Ruby pour obtenir la gestion des erreurs, vérifier le résultat, etc.
noraj
2

Chemin à la rescousse!

Pathname('/a/b/c/d.txt').dirname.mkpath
Vadym Tyemirov
la source
C'est moins intuitif que la réponse acceptée. Aussi la documentation pour la méthode transmise à FileUtils ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/…
noraj
La question est: "Je veux stocker un fichier sous /a/b/c/d.txt, mais je ne sais pas si l'un de ces répertoires existe". Ma solution permet d'utiliser le chemin du fichier existant ('/a/b/c/d.txt'), et, sans analyse séparée, de créer tous les dossiers.
Vadym Tyemirov
Vous voulez dire que cela permet de faire FileUtils.mkdir_p '/a/b/c'+ créer d.txten même temps?
noraj
Non, au lieu de cela, il permet Pathname('/a/b/c/d.txt').dirname.mkpathet File.write('/a/b/c/d.txt', content)sans filename = '/a/b/c/d.txt'.rpartition('/').lastet le reste de l'analyse
Vadym Tyemirov
0

Vous pouvez également utiliser votre propre logique

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

Donc si le chemin est «tmp / a / b / c» si «tmp» n'existe pas, «tmp» est créé, alors «tmp / a /» et ainsi de suite.

kamal patwa
la source
On éviterait de réinventer la roue.
noraj