루비의 디렉토리를 재귀 적으로 나열하는 한 줄?


96

Ruby에서 디렉토리 배열 (파일 제외)을 얻는 가장 빠르고 최적화 된 한 줄짜리 방법은 무엇입니까?

파일을 포함하는 것은 어떻습니까?


2
가장 빠르고 가장 최적화 된 단일 라이너는 읽기 / 유지 관리가 불가능할 수 있습니다. 그리고 벤치 마크와 빠른 테스트를 통해이를 확인할 수 있습니다.
Tin Man

답변:


180
Dir.glob("**/*/") # for directories
Dir.glob("**/*") # for all files

대신 Dir.glob(foo)쓸 수도 있습니다 Dir[foo](하지만 Dir.glob블록을 사용할 수도 있습니다.이 경우 배열을 생성하는 대신 각 경로를 생성합니다).

Ruby Glob 문서


10
Dir.glob("**/")심볼릭 링크도 원하지 않는 한 사용
johannes

6
숨겨진 파일과 디렉토리는 어떻습니까?
alediaferia

6
일치 결과에 도트 파일을 포함하려면 File::FNM_DOTMATCH플래그를 사용하십시오 .
x-yuri

2
감사합니다 @ x-yuri! btw 플래그는 다음과 같이 지정됩니다.Dir.glob("**/*", File::FNM_DOTMATCH)
vlz



31

디렉토리 목록을 보려면

Dir['**/']

파일 목록은 더 어렵습니다. Unix 디렉토리에서도 파일이기 때문에 유형을 테스트하거나 다른 항목의 부모 인 반환 된 목록에서 항목을 제거해야합니다.

Dir['**/*'].reject {|fn| File.directory?(fn) }

그리고 모든 파일 및 디렉토리 목록을 간단히

Dir['**/*']

그는 "파일 만 포함"이 아니라 "파일 포함"이라고 말 했으므로 디렉토리를 제거 할 필요가 없습니다.
sepp2k

1
@ sepp2k 예, irb를 가지고 놀 때이 부분을 놓쳤습니다. 하지만 누군가 비슷한 것을 검색 할 수있는 경우를 대비하여 여기에 남겨 둡니다. :-)
MBO

7

패스트 원 라이너

디렉토리 만

`find -type d`.split("\n")

디렉토리 및 일반 파일

`find -type d -or -type f`.split("\n")`

순수한 아름다운 루비

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)

1
False : Dir.glob ( "# {DIRECTORY} / ** / * /"). map {| directory | Pathname.new (directory)}
Robert Ross

누구든지 그 end.select {}.flatten()부분을 설명 할 수 있습니까 ? 나는 전체적으로 기능을 좋아합니다. 배열 배열을 생성 할 것 같습니까? 다음 elseif과 같이 부분 을 수행 rec_path(child, file) << child.to_s할 수 있습니까? 배열에 할당하고 문자열 배열을 얻을 수 있습니까? 감사!
MCP

7

여기에 다른 답변에서 언급했듯이 Dir.glob. 폴더에는 이상한 문자가 많이 포함될 수 있으며 glob 인수는 패턴이므로 일부 문자에는 특별한 의미가 있습니다. 따라서 다음과 같은 작업을하는 것은 안전하지 않습니다.

Dir.glob("#{folder}/**/*")

대신 다음을 수행하십시오.

Dir.chdir(folder) { Dir.glob("**/*").map {|path| File.expand_path(path) } }

2

PHP 또는 다른 언어에서 디렉토리와 모든 하위 디렉토리의 내용을 얻으려면 몇 줄의 코드를 작성해야하지만 Ruby에서는 두 줄이 필요합니다.

require 'find'
Find.find('./') do |f| p f end

이것은 현재 디렉토리와 모든 하위 디렉토리의 내용을 인쇄합니다.

또는 더 짧게 ’**’표기법을 사용할 수 있습니다 .

p Dir['**/*.*']

동일한 결과를 얻기 위해 PHP 또는 Java로 몇 줄을 작성합니까?


13
직접부터 붙여 복사에 대한을 downvoted mustap.com/rubyzone_post_162_recursive-directory-listing ... 소스를 인용하지 않고
eckza

@kivetros 나는 링크 :-)의 보관 된 버전을 포함하는 답을 편집
onebree

0

한 줄 솔루션은 아니지만 이것이 루비 호출을 사용하는 가장 좋은 방법이라고 생각합니다.

먼저 모든 파일을 재귀 적으로
삭제하고 두 번째는 모든 빈 디렉토리를 삭제합니다.

Dir.glob("./logs/**/*").each { |file| File.delete(file) if File.file? file }
Dir.glob("./logs/**/*/").each { |directory| Dir.delete(directory) }

3
파일 / 디렉터리 삭제를 원하지 않습니다.
Darek Nędza 2015

한 줄에 파일 + 디렉토리 모두에 대해이 작업을 수행하는 방법은 무엇입니까?
vipin8169

0

다음은 Rails 프로젝트 디렉토리의 동적 검색을 Dir.glob과 결합하는 예입니다.

dir = Dir.glob(Rails.root.join('app', 'assets', 'stylesheets', '*'))

나는 >>이 시도 config.assets.paths << Rails.root.join("app", "assets", "*"),하지만 여전히하여 폴더 자산 내부의 하위 폴더 및 파일을 볼 수 없었다Rails.application.config.assets.paths
vipin8169

-1
Dir.open(Dir.pwd).map { |h| (File.file?(h) ? "#{h} - file" : "#{h} - folder") if h[0] != '.' }

점은 nil을 반환하고 압축을 사용합니다.


1
이것은 너무 우아하지 않으며 그렇게하려면 몇 줄 더 있어야합니다
onebree
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.