однострочник для рекурсивного перечисления каталогов в ruby?

<p>какой самый быстрый, самый оптимизированный, однострочный способ получения массива каталогов (исключая файлы) в ruby?</p><p>как насчет включения файлов?</p>

<pre><code>dir.glob("**/*/") # for directories dir.glob("**/*") # for all files </code></pre><p>вместо <code>dir.glob(foo)</code> вы также можете написать <code>dir[foo]</code> (однако <code>dir.glob</code> также может занять блок, и в этом случае он будет выдавать каждый путь вместо создания массива).</p><p> <a href="http://ruby-doc.org/core-2.2.0/dir.html#method-c-glob">ruby glob docs</a> </p>

<p>я полагаю, что ни одно из решений здесь не имеет дело со скрытыми каталогами (например, '.test'):</p><pre><code>require 'find' find.find('.') { |e| puts e if file.directory?(e) } </code></pre>

<p>для списка каталогов попробуйте</p><pre><code>dir['**/'] </code></pre><p>список файлов сложнее, потому что в каталоге unix также есть файл, поэтому вам нужно проверить тип или удалить записи из возвращенного списка, который является родительским для других записей.</p><pre><code>dir['**/*'].reject {|fn| file.directory?(fn) } </code></pre><p>а для списка всех файлов и каталогов просто</p><pre><code>dir['**/*'] </code></pre>

<h1>быстро один лайнер</h1><p>только каталоги</p><pre><code>`find -type d`.split("\n") </code></pre><p>каталоги и нормальные файлы</p><pre><code>`find -type d -or -type f`.split("\n")` </code></pre><h1>чисто красивый рубин</h1><pre><code>require "pathname" def rec\_path(path, file= false) puts path path.children.collect do |child| if file and child.file? child elsif child.directory? rec\_path(child, file) + [child] end end.select { |x| x }.flatten(1) end # only directories rec\_path(pathname.new(dir), false) # directories and normal files rec\_path(pathname.new(dir), true) </code></pre>

<p>как отмечено в других ответах здесь, вы можете использовать <code>dir.glob</code>. имейте в виду, что в папках может быть много странных символов, а аргументы glob - это шаблоны, поэтому некоторые символы имеют особое значение. поэтому небезопасно делать что-то вроде следующего:</p><pre><code>dir.glob("#{folder}/**/*") </code></pre><p>вместо этого сделайте:</p><pre><code>dir.chdir(folder) { dir.glob("**/*").map {|path| file.expand\_path(path) } } </code></pre>

<p>в php или других языках для получения содержимого каталога и всех его подкаталогов вам нужно написать несколько строк кода, но в ruby требуется 2 строки:</p><pre><code>require 'find' find.find('./') do |f| p f end </code></pre><p>это напечатает содержимое текущего каталога и всех его подкаталогов.</p><p>или короче, вы можете использовать нотацию <code>’**’</code>:</p><pre><code>p dir['**/*.*'] </code></pre><p>сколько строк вы напишите в php или в java, чтобы получить тот же результат?</p>

<p>вот пример, который сочетает динамическое обнаружение каталога проекта rails с dir.glob:</p><pre><code>dir = dir.glob(rails.root.join('app', 'assets', 'stylesheets', '*')) </code></pre>

<p>хотя это не однострочное решение, я думаю, что это лучший способ сделать это с помощью вызовов ruby.</p><p>сначала рекурсивно удалите все файлы<br> затем удалите все пустые каталоги.</p><pre><code>dir.glob("./logs/**/*").each { |file| file.delete(file) if file.file? file } dir.glob("./logs/**/*/").each { |directory| dir.delete(directory) } </code></pre>