Dir.glob для получения всех файлов csv и xls в папке
folder_to_analyze = ARGV.first
folder_path = File.join(Dir.pwd, folder_to_analyze)
unless File.directory?(folder_path)
puts "Error: #{folder_path} no es un folder valido."
exit
end
def get_csv_file_paths(path)
files = []
Dir.glob(path + '/**/*.csv').each do |f|
files << f
end
return files
end
def get_xlsx_file_path(path)
files = []
Dir.glob(path + '/**/*.xls').each do |f|
files << f
end
return files
end
files_to_process = []
files_to_process << get_csv_file_paths(folder_path)
files_to_process << get_xlsx_file_path(folder_path)
puts files_to_process[1].length # Not what I want, I want:
# puts files_to_process.length
Я пытаюсь сделать простой script в Ruby, который позволяет мне вызывать его из командной строки, например ruby counter.rb mailing_list1
, и он переходит в папку и учитывает все файлы .csv и .xls.
Я намерен работать с каждым файлом, получая количество строк и т.д.
В настоящее время массив files_to_process
на самом деле является массивом массива - я этого не хочу. Я хочу иметь один массив из файлов .csv и .xls.
Так как я не знаю, как уступить из вызова Dir.glob
, я добавил их в массив и вернул это.
Как это сделать, используя один массив?
Ответы
Ответ 1
Ну, урожайность проста. Просто yield
.
def get_csv_file_paths(path)
Dir.glob(path + '/**/*.csv').each do |f|
yield f
end
end
def get_xlsx_file_path(path)
Dir.glob(path + '/**/*.xls').each do |f|
yield f
end
end
files_to_process = []
get_csv_file_paths(folder_path) {|f| files_to_process << f }
get_xlsx_file_path(folder_path) {|f| files_to_process << f }
puts files_to_process.length
Каждый метод в ruby может быть передан блоком. И ключевое слово yield
отправляет данные в этот блок. Если блок может быть или не может быть предоставлен, yield
обычно используется с block_given?
.
yield f if block_given?
Update
Код можно упростить, передав свой блок непосредственно на glob.each
:
def get_csv_file_paths(path, &block)
Dir.glob(path + '/**/*.txt').each(&block)
end
def get_xlsx_file_path(path, &block)
Dir.glob(path + '/**/*.xls').each(&block)
end
Несмотря на то, что это преобразование блока /proc - это немного продвинутая тема.
Ответ 2
Просто вставьте расширения файлов вместе в одну группу:
Dir[path + "/**/*.{csv,xls}"]
Ответ 3
def get_folder_paths(root_path)
Dir.glob('**/*.csv') + Dir.glob('**/*.xls')
end
folder_path = File.join(Dir.pwd, ARGV.first || '')
raise "#{folder_path} is not a valid folder" unless File.directory?(folder_path)
puts get_folder_paths(folder_path).length
Метод get_folder_paths
возвращает массив файлов CSV и XLS. Создание массива имен файлов может быть не тем, что вы действительно хотите, особенно если их много. Подход, использующий Enumerator, возвращаемый Dir.glob, был бы более уместным в этом случае, если вам сначала не понадобилось количество файлов.