Изменить заголовки для определенных столбцов в файле CSV - PullRequest
0 голосов
/ 03 мая 2018

У меня есть файл CSV, который я хочу изменить заголовки только для определенных столбцов (около 20 из них в моем реальном файле). Вот пример файла CSV:

Файл CSV

"name","blah_01_blah","foo_1_01_foo","bacon_01_bacon","bacon_02_bacon"
"John","yucky","summer","yum","food"
"Mary","","","cool","sundae"

Я пытался сделать это с классом File / IO, но когда он читает файл для выполнения gsub, он удаляет все кавычки вокруг каждой строки, разделенные запятыми. Вот код, который я использую:

код рубина

file = 'file.csv'

replacements = {
    'blah_01_blah' => 'newblah1',
    'foo_01_foo' => 'coolfoo1',
    'bacon_01_bacon' => 'goodpig1',
    'bacon_01_bacon' => 'goodpig2'
}

matcher = /#{replacements.keys.join('|')}/

outdata = File.read(file).gsub(matcher, replacements)

File.open(file, 'w') do |out|
out << outdata
end

В результате я получаю в файле CSV:

Новый файл CSV

name,blah_01_blah,foo_1_01_foo,bacon_01_bacon,bacon_02_bacon
John,yucky,summer,yum,food
Mary,"","",cool,sundae

Он хранит кавычки в пустых полях, но выводит их вокруг строк в других местах. Я хочу сохранить эти кавычки на случай, если по какой-то причине мошенническая запятая окажется где-то в строке, поэтому она не будет сброшена. Как я могу изменить заголовки, не теряя кавычки вокруг строк?

РЕДАКТИРОВАТЬ - это то, что я хочу, чтобы файл выглядел в конце.

Ожидаемый результат CSV-файл

"name","newblah1","coolfoo1","goodpig1","goodpig2"
"John","yucky","summer","yum","food"
"Mary","","","cool","sundae"

Спасибо!

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Давайте сначала создадим входной CSV-файл.

text =<<_
"name","blah_01_blah","foo_1_01_foo","bacon_01_bacon","bacon_02_bacon"
"John","yucky","summer","yum","food"
"Mary","","","cool","sundae"
_

file_in  = 'file_in.csv'
file_out = 'file_out.csv'
File.write(file_in, text)
  #=> 137

Вот хеш replacements, который я немного упростил.

replacements = {'blah_01_blah'=>'newblah1', 'foo_01_foo'=>'coolfoo1',
                'bacon_01_bacon'=>'goodpig1'}

Первая задача - изменить этот хеш, чтобы при отсутствии ключа k replacements[k] вернул k. Для этого мы используем метод Hash # default_proc = .

replacements.default_proc = ->(_,k) { k }

Вот два примера использования этого хеша.

replacements['bacon_01_bacon']
  #=> "goodpig1"
replacements['name']
  #=> "name"`

Последнее следует из того, что replacements не имеет ключа 'name'.

Код выглядит следующим образом.

require 'csv'

f_in = CSV.read(file_in, headers:true)
CSV.open(file_out, 'w') do |csv_out|
  csv_out << replacements.values_at(*f_in.headers)
  f_in.each { |row| csv_out << row }
end
  #=> #<CSV::Table mode:col_or_row row_count:3>

Обратите внимание, что

f_in.headers
  #=> ["name", "blah_01_blah", "foo_1_01_foo", "bacon_01_bacon", "bacon_02_bacon"]

Давайте посмотрим на выходной файл.

puts File.read(file_out)

печать

name,newblah1,foo_1_01_foo,goodpig1,bacon_02_bacon
John,yucky,summer,yum,food
Mary,"","",cool,sundae
0 голосов
/ 03 мая 2018

Вам вообще не нужно обрабатывать CSV:

File.write(
  file,
  File.readlines(file).tap do |lines|
    lines.first.gsub!(matcher, replacements)
  end.join
)

File#readlines.

Хитрость в том, что мы имеем дело только с первой строкой, как с простым текстом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...