Jak tworzyć katalogi rekurencyjnie w Rubim?

102

Chcę zapisać plik jako /a/b/c/d.txt, ale nie wiem, czy któryś z tych katalogów istnieje i muszę je rekurencyjnie utworzyć, jeśli to konieczne. Jak można to zrobić w rubinie?

Jan
źródło

Odpowiedzi:

198

Zastosowanie mkdir_p:

FileUtils.mkdir_p '/a/b/c'

_pTo przeżytek UNIX dla rodzica / ścieżki można również wykorzystać alias mkpathjeśli to ma większy sens dla Ciebie.

FileUtils.mkpath '/a/b/c'

W Ruby 1.9 FileUtils zostało usunięte z rdzenia, więc będziesz musiał require 'fileutils'.

Harmon Wood
źródło
9
+1. FileUtilsi Pathnameto prawdopodobnie z najważniejszych narzędzi dla Ruby skryptów powłoki.
Jörg W Mittag,
21

Użyj mkdir_p do rekurencyjnego tworzenia katalogu

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

FileUtils.mkdir_p(path) unless File.exists?(path)
ferbass
źródło
6

Jeśli pracujesz na maszynach z systemem Unixy, nie zapominaj, że zawsze możesz uruchomić polecenie powłoki w Rubim, umieszczając je w odwrotnych znakach.

`mkdir -p /a/b/c`
Matthew Schinckel
źródło
Jednak bycie tak pozytywnym jest.
Matthew Schinckel
1
Umieszczenie polecenia systemowego w podprocesie nie jest najlepszym pomysłem. Lepiej zrobić to za pomocą standardowej biblioteki Ruby, aby uzyskać obsługę błędów, sprawdzić wynik itp.
noraj
2

Ścieżka na ratunek!

Pathname('/a/b/c/d.txt').dirname.mkpath
Vadym Tyemirov
źródło
Jest to mniej intuicyjne niż zaakceptowana odpowiedź. Również dokumentacja metody jest przekazywana do FileUtils ruby-doc.org/stdlib-2.6.5/libdoc/pathname/rdoc/…
noraj
Pytanie brzmi: „Chcę zapisać plik jako /a/b/c/d.txt, ale nie wiem, czy któryś z tych katalogów istnieje”. Moje rozwiązanie pozwala na wykorzystanie istniejącej ścieżki do plików („/a/b/c/d.txt”) i, bez oddzielnego analizowania, stworzyć wszystkie foldery.
Vadym Tyemirov
Masz na myśli to, że pozwala robić FileUtils.mkdir_p '/a/b/c'+ tworzyć d.txtw tym samym czasie?
noraj
Nie, zamiast tego pozwala Pathname('/a/b/c/d.txt').dirname.mkpathi File.write('/a/b/c/d.txt', content)bez filename = '/a/b/c/d.txt'.rpartition('/').lastoraz reszta analizy
Vadym Tyemirov
0

Możesz także użyć własnej logiki

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

Jeśli więc ścieżka to „tmp / a / b / c”, jeśli „tmp” nie istnieje, zostanie utworzony „tmp”, a następnie zostanie utworzony „tmp / a /” i tak dalej.

kamal patwa
źródło
Można by uniknąć ponownego wynalezienia koła.
noraj,