Reputation: 1467
I wrote the following script to iterate through a directory, it's subdirectories and their files:
def self.search_files_in_dir_for(dir, strings)
results = {}
puts "Initializing test ..."
Dir.foreach(dir) do |file|
next if file == '.' or file == '..'
puts 'TEST: Testing dir "' + dir + "/" + file + '"'
if File.file?(file)
puts 'TEST: Testing "' + dir + "/" + file + '"'
line_number = 0
IO.foreach(file) do |line|
line_number = line_number + 1
if strings.any? { |string| line.include?(string) }
string = strings.detect { |string| line.include?(string) }
puts source = file + ":" + line_number.to_s
results[source] = string
end
end
elsif File.directory?(file)
# Search child directories
search_files_in_dir_for(File.join(dir, file), strings)
end
end
end
Given the followiing dir + file structure:
- views
- application
- abcdefg
- _partial2.html.erb
- _partial1.html.erb
- layouts
- application.html.erb
and when passing the path of the views
directory as dir
, I get that output:
Initializing test ...
TEST: Testing dir "views/application"
TEST: Testing dir "views/layouts"
I would expect something like this:
Initializing test ...
TEST: Testing dir "views/application"
TEST: Testing dir "views/application/abcdefg"
TEST: Testing "views/application/abcdefg/_partial2.html.erb"
TEST: Testing "views/application/_partial1.html.erb"
TEST: Testing dir "views/layouts"
TEST: Testing "views/layouts/application.html.erb"
What am I doing wrong in that script?
Upvotes: 2
Views: 1055
Reputation: 54223
A noticeably shorter version, using Pathname
and Pathname.glob
:
require 'pathname'
files, dirs = Pathname.glob('**/*').partition(&:file?)
It gives you two arrays : one with all the files in the current directory, the other with all the subfolders.
For a specific dir
:
files, dirs = Pathname.glob(File.join(dir, '**/*')).partition(&:file?)
You'd just need to parse the content of files
It looks like you're trying to replicate grep
, ack
or git grep
Here's a modified version of your code. The biggest problem was that file
was a relative path. File.file?(file)
was always returning false
:
@results = {}
def search_files_in_dir_for(dir, strings)
Dir.foreach(dir) do |file|
complete_path = File.join(dir, file)
next if file == '.' or file == '..'
if File.file?(complete_path)
puts "TEST: Testing '#{complete_path}'"
line_number = 0
IO.foreach(complete_path) do |line|
line_number = line_number + 1
if strings.any? { |string| line.include?(string) }
string = strings.detect { |string| line.include?(string) }
source = complete_path + ":" + line_number.to_s
@results[source] = string
end
end
else
# Search child directories
search_files_in_dir_for(complete_path, strings)
end
end
end
search_files_in_dir_for(..., [..., ...])
p @results
Upvotes: 2