¿Cómo crear directorios de forma recursiva en ruby?

101

Quiero almacenar un archivo como /a/b/c/d.txt, pero no sé si existe alguno de estos directorios y necesito crearlos de forma recursiva si es necesario. ¿Cómo se puede hacer esto en rubí?

ene
fuente

Respuestas:

197

Utilizar mkdir_p:

FileUtils.mkdir_p '/a/b/c'

El _pes un vestigio de UNIX para los padres / ruta también se puede utilizar el alias mkpathsi eso tiene más sentido para usted.

FileUtils.mkpath '/a/b/c'

En Ruby 1.9 FileUtils se eliminó del núcleo, por lo que tendrá que hacerlo require 'fileutils'.

Madera Harmon
fuente
9
+1. FileUtilsy Pathnameson probablemente las herramientas más importantes para la creación de scripts de shell Ruby.
Jörg W Mittag
21

Utilice mkdir_p para crear directorio de forma recursiva

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

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

Si está ejecutando en máquinas Unixy, no olvide que siempre puede ejecutar un comando de shell bajo ruby ​​colocándolo entre comillas invertidas.

`mkdir -p /a/b/c`
Matthew Schinckel
fuente
Sin embargo, ser tan positivo es.
Matthew Schinckel
1
Poner el comando del sistema en un subproceso no es la mejor idea. Es mejor hacerlo con la biblioteca estándar de Ruby para obtener el manejo de errores, verificar el resultado, etc.
noraj
2

Pathname al rescate!

Pathname('/a/b/c/d.txt').dirname.mkpath
Vadym Tyemirov
fuente
Esto es menos intuitivo que la respuesta aceptada. También el documento para el método reenvía a FileUtils ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/…
noraj
La pregunta es: "Quiero almacenar un archivo como /a/b/c/d.txt, pero no sé si existe alguno de estos directorios". Mi solución permite usar la ruta del archivo existente ('/a/b/c/d.txt') y, sin un análisis por separado, crear todas las carpetas.
Vadym Tyemirov
¿Quieres decir que esto permite hacer FileUtils.mkdir_p '/a/b/c'+ crear d.txtal mismo tiempo?
noraj
No, en cambio permite Pathname('/a/b/c/d.txt').dirname.mkpathy File.write('/a/b/c/d.txt', content)sin filename = '/a/b/c/d.txt'.rpartition('/').lasty el resto del análisis
Vadym Tyemirov
0

También puedes usar tu propia lógica

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

Entonces, si la ruta es 'tmp / a / b / c' si 'tmp' no existe, se crea 'tmp', entonces 'tmp / a /' y así sucesivamente.

kamal patwa
fuente
Se evitaría reinventar la rueda.
noraj