답변:
바로 가기 옵션도 있습니다
Dir["/path/to/search/*"]
폴더 또는 하위 폴더에서 모든 Ruby 파일을 찾으려면 다음을 수행하십시오.
Dir["/path/to/search/**/*.rb"]
./...
대신 사용하십시오~/
./
현재 디렉토리를 의미하는 반면 /
루트 마운트 지점이며 ~/
사용자의 홈 디렉토리입니다. 전체 프로젝트를 다른 곳으로 옮기면 첫 번째 프로젝트는 작동하지만 다른 두 프로젝트는 효과가 없습니다.
Dir.entries(folder)
예:
Dir.entries(".")
출처 : http://ruby-doc.org/core/classes/Dir.html#method-c-entries
Dir#glob
예를 들어 언급되었을 수도 있습니다) 다른 사람이 정말 좋은 답변을 게시하는 것을 막을 수있는 것은 없습니다. '과정, 나는 주로 "유리 반 전체"일종의 남자 ...
Dir
거의 사용 하지 않으며 필요할 때마다 문서를 읽어야합니다. 내 질문과 답변을 여기에 게시하여 나중에 찾을 수 있으며 같은 질문을 가진 사람을 도울 수도 있습니다. SO 팟 캐스트에서 그런 행동에는 아무런 문제가 없다고 들었습니다. 더 나은 답변이 있으면 게시하십시오. 나는 내가 아는 것을 게시했다. 나는 루비 닌자가 아니다. 나는 가장 많은 표를 얻은 답변을 정기적으로 받아들입니다.
Dir[]
또는 더 나은 옵션 일 수 있습니다 Dir.glob
. 때 path = '/tmp'
, 비교 : Dir.glob("#{path}/*")
대 Dir.entries(path)
. 반환 값은 약간 다르지만 ( ".", "..") 후자는 한 눈에 파악하기가 더 쉽습니다.
다음 조각은 정확히 디렉토리 내 파일을 건너 뛰는 하위 디렉토리 및 이름 표시 "."
, ".."
점으로 구분 된 폴더를 :
Dir.entries("your/folder").select {|f| !File.directory? f}
...select {|f| File.file? f}
더 명확한 의미와 더 짧은 구문을 위해 할 수도 있습니다 .
Dir.entries("your/folder").select {|f| File.file? f}
!File.directory?
작동하지만 작동하지 File.file?
않습니다.
.reject {|f| File.directory? f}
보다 깨끗해 보입니다 .select{|f| !File.directory? f}
. 아, 이제 첫 번째 의견도 보았습니다 ... 또한 좋습니다.
모든 파일 (엄격한 파일 만)을 재귀 적으로 가져 오려면 :
Dir.glob('path/**/*').select{ |e| File.file? e }
또는 디렉토리 File.file?
가 아닌 모든 것 ( 비정규 파일을 거부 함) :
Dir.glob('path/**/*').reject{ |e| File.directory? e }
실제로 Find#find
패턴 기반 조회 방법을 사용 하는 Dir.glob
것이 더 좋습니다. "루비에서 디렉토리를 재귀 적으로 나열하는 한 줄짜리"에 대한이 답변을 참조하십시오. .
이것은 나를 위해 작동합니다 :
숨겨진 파일을 원하지 않으면 [1] Dir []을 사용하십시오 .
# With a relative path, Dir[] will return relative paths
# as `[ './myfile', ... ]`
#
Dir[ './*' ].select{ |f| File.file? f }
# Want just the filename?
# as: [ 'myfile', ... ]
#
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.basename f }
# Turn them into absolute paths?
# [ '/path/to/myfile', ... ]
#
Dir[ '../*' ].select{ |f| File.file? f }.map{ |f| File.absolute_path f }
# With an absolute path, Dir[] will return absolute paths:
# as: [ '/home/../home/test/myfile', ... ]
#
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }
# Need the paths to be canonical?
# as: [ '/home/test/myfile', ... ]
#
Dir[ '/home/../home/test/*' ].select{ |f| File.file? f }.map{ |f| File.expand_path f }
이제 Dir.entries 는 숨겨진 파일을 반환하고 와일드 카드 별표 (디렉토리 이름으로 변수를 전달할 수 있음)는 필요하지 않지만 기본 이름을 직접 반환하므로 File.xxx 함수가 작동하지 않습니다. .
# In the current working dir:
#
Dir.entries( '.' ).select{ |f| File.file? f }
# In another directory, relative or otherwise, you need to transform the path
# so it is either absolute, or relative to the current working dir to call File.xxx functions:
#
home = "/home/test"
Dir.entries( home ).select{ |f| File.file? File.join( home, f ) }
[1] .dotfile
유닉스에서 나는 Windows에 대해 모른다
루비 2.5에서는 이제 사용할 수 있습니다 Dir.children
. "."을 제외하고 파일 이름을 배열로 가져옵니다. ".."
예:
Dir.children("testdir") #=> ["config.h", "main.rb"]
디렉토리의 모든 파일 이름을 가져 오는 동안이 스 니펫은 디렉토리 [ .
, ..
] 및로 시작하는 숨겨진 파일을 모두 거부하는 데 사용할 수 있습니다 ..
files = Dir.entries("your/folder").reject {|f| File.directory?(f) || f[0].include?('.')}
Dir.entries
절대 파일 경로가 아닌 로컬 파일 이름을 반환합니다. 반면에 File.directory?
절대 파일 경로가 필요합니다. 이 코드는 예상대로 작동하지 않습니다.
이 코드는 (전역 경로없이) 확장자를 가진 파일 이름 만 반환합니다.
Dir.children("/path/to/search/")
이것이 나를 위해 작동하는 것입니다.
Dir.entries(dir).select { |f| File.file?(File.join(dir, f)) }
Dir.entries
문자열 배열을 반환합니다. 그런 다음 현재 작업 디렉토리와 동일 File.file?
하지 않은 경우 파일의 전체 경로를 제공해야합니다 dir
. 이것이 바로이 이유 File.join()
입니다.
다음을 사용하고 싶을 수도 있습니다 Rake::FileList
( rake
종속성이있는 경우).
FileList.new('lib/*') do |file|
p file
end
API에 따르면 :
FileLists가 게으르다. 파일 목록에 포함 할 수있는 파일에 대한 glob 패턴 목록이 제공되면 파일 구조를 검색하여 파일을 찾는 대신 FileList는 나중에 사용하기 위해 패턴을 보유합니다.
당신은 파일 이름의 배열을 취득하려는 경우 심볼릭 링크를 포함하여 , 사용
Dir.new('/path/to/dir').entries.reject { |f| File.directory? f }
또는
Dir.new('/path/to/dir').reject { |f| File.directory? f }
당신이 가고 싶은 경우 심볼릭 링크없이 사용
Dir.new('/path/to/dir').select { |f| File.file? f }
다른 답변에서 볼 수 있듯이 모든 파일을 재귀 적으로 얻으려면 Dir.glob('/path/to/dir/**/*')
대신 사용 Dir.new('/path/to/dir')
하십시오.
*.*
이 스레드의 제안 외에도 Dir.glob를 사용하여 도트 파일 (.gitignore 등)을 반환 해야하는 경우 플래그를 포함해야한다고 언급하고 싶습니다.
Dir.glob("/path/to/dir/*", File::FNM_DOTMATCH)
기본적으로 Dir.entries 현재 상위 디렉토리뿐만 아니라 도트 파일도 포함합니다.
관심있는 사람에게는 실행 시간에 여기에 대한 답변이 어떻게 비교되는지 궁금합니다. 여기에 중첩 된 계층 구조에 대한 결과가 있습니다. 처음 세 가지 결과는 비재 귀적입니다.
user system total real
Dir[*]: (34900 files stepped over 100 iterations)
0.110729 0.139060 0.249789 ( 0.249961)
Dir.glob(*): (34900 files stepped over 100 iterations)
0.112104 0.142498 0.254602 ( 0.254902)
Dir.entries(): (35600 files stepped over 100 iterations)
0.142441 0.149306 0.291747 ( 0.291998)
Dir[**/*]: (2211600 files stepped over 100 iterations)
9.399860 15.802976 25.202836 ( 25.250166)
Dir.glob(**/*): (2211600 files stepped over 100 iterations)
9.335318 15.657782 24.993100 ( 25.006243)
Dir.entries() recursive walk: (2705500 files stepped over 100 iterations)
14.653018 18.602017 33.255035 ( 33.268056)
Dir.glob(**/*, File::FNM_DOTMATCH): (2705500 files stepped over 100 iterations)
12.178823 19.577409 31.756232 ( 31.767093)
이들은 다음 벤치마킹 스크립트로 생성되었습니다.
require 'benchmark'
base_dir = "/path/to/dir/"
n = 100
Benchmark.bm do |x|
x.report("Dir[*]:") do
i = 0
n.times do
i = i + Dir["#{base_dir}*"].select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.glob(*):") do
i = 0
n.times do
i = i + Dir.glob("#{base_dir}/*").select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.entries():") do
i = 0
n.times do
i = i + Dir.entries(base_dir).select {|f| !File.directory? File.join(base_dir, f)}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir[**/*]:") do
i = 0
n.times do
i = i + Dir["#{base_dir}**/*"].select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.glob(**/*):") do
i = 0
n.times do
i = i + Dir.glob("#{base_dir}**/*").select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.entries() recursive walk:") do
i = 0
n.times do
def walk_dir(dir, result)
Dir.entries(dir).each do |file|
next if file == ".." || file == "."
path = File.join(dir, file)
if Dir.exist?(path)
walk_dir(path, result)
else
result << file
end
end
end
result = Array.new
walk_dir(base_dir, result)
i = i + result.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
x.report("Dir.glob(**/*, File::FNM_DOTMATCH):") do
i = 0
n.times do
i = i + Dir.glob("#{base_dir}**/*", File::FNM_DOTMATCH).select {|f| !File.directory? f}.length
end
puts " (#{i} files stepped over #{n} iterations)"
end
end
파일 수의 차이는 Dir.entries
기본적으로 숨겨진 파일 을 포함 하기 때문 입니다. Dir.entries
이 경우 파일이 디렉토리인지 확인하기 위해 파일의 절대 경로를 다시 작성해야했기 때문에 시간이 조금 더 걸리지 만 재귀 적 인 경우에도 다른 옵션보다 계속 더 오래 걸리고 있습니다. 이것은 모두 OSX에서 루비 2.5.1을 사용했습니다.
def get_path_content(dir)
queue = Queue.new
result = []
queue << dir
until queue.empty?
current = queue.pop
Dir.entries(current).each { |file|
full_name = File.join(current, file)
if not (File.directory? full_name)
result << full_name
elsif file != '.' and file != '..'
queue << full_name
end
}
end
result
end
디렉토리와 모든 하위 디렉토리에서 파일의 상대 경로를 반환합니다.
IRB 컨텍스트에서 다음을 사용하여 현재 디렉토리의 파일을 가져올 수 있습니다.
file_names = `ls`.split("\n")
다른 디렉토리 에서도이 작업을 수행 할 수 있습니다.
file_names = `ls ~/Documents`.split("\n")