Givens
Нам даны следующие данные.
Пути для двух входных файлов:
fname1 = 't1.csv'
fname2 = 't2.csv'
Путь для выводаfile:
fname3 = 't3.csv'
Имена заголовков для сопоставления в каждом из двух входных файлов:
target1 = 'B'
target2 = 'E'
Я предполагаю, что (как в случае с примером) двафайлы обязательно должны содержать одинаковое количество строк.
Создание тестовых файлов
Давайте сначала создадим два файла:
str = [%w|A B C|, %w|1 1 1|, %w|2 2 2|, %w|3 4 5|, %w|6 9 9|].
map { |a| a.join(",") }.join("\n")
#=> "A,B,C\n1,1,1\n2,2,2\n3,4,5\n6,9,9"
File.write(fname1, str)
#=> 29
str = [%w|D E F|, %w|21 1 41|, %w|22 5 42|, %w|23 8 45|, %w|26 9 239|].
map { |a| a.join(",") }.join("\n")
#=> "D,E,F\n21,1,41\n22,5,42\n23,8,45\n26,9,239"
File.write(fname2, str)
#=> 38
Считать входные файлы в CSV::Table
объекты
При чтении fname1
я буду использовать опцию :header_converters
для преобразования заголовка "B"
до "B/E"
. Обратите внимание, что для этого не требуется знание местоположения столбца с заголовком "B"
(или чем бы то ни было).
require 'csv'
new_target1 = target1 + "/" + target2
#=> "B/E"
csv1 = CSV.read(fname1, headers: true,
header_converters: lambda { |header| header==target1 ? new_target1 : header})
csv2 = CSV.read(fname2, headers: true)
Создание массивов заголовков для записи из каждого входного файла
headers1 = csv1.headers
#=> ["A", "B/E", "C"]
headers2 = csv2.headers - [target2]
#=> ["D", "F"]
Создание выходного файла
Сначала мы запишем новые заголовки headers1 + headers2
в выходной файл.
Далее,для каждого индекса строки i
(i = 0
, соответствующего первой строке после строки заголовка в каждом файле), для которого выполняется условие, мы записываем как одну строку элементы csv1[i]
и csv2[i]
, которые являютсяв столбцах, имеющих заголовки в headers1
и headers2
. Условие, которое должно быть выполнено для записи строк с индексом i
, заключается в том, что i
удовлетворяет:
csv1[i][new_target1] == csv2[i][target2] #=> true
Теперь откройте fname3
для записи, запишите заголовки и затем тело. 1068 *
Давайте подтвердим, что написанное верно.
puts File.read(fname3)
A,B/E,C,D,F
1,1,1,21,41
6,9,9,26,239