Replacing Text in One CSV Column Using Fastercsv

Replacing text in one CSV column using FasterCSV

There's a couple of things you can change in the initialization line that will help. Change:

csv = FCSV.read(filename, :headers => true, :return_headers => true, :encoding => 'u') 

to:

csv = FCSV.read(filename, :headers => true, :encoding => 'u') 

I'm using CSV, which is FasterCSV only it's part of Ruby 1.9. This will create a CSV file in the current directory called "temp.csv" with a modified 'FName' field:

require 'csv'

data = "ID,FName,LName\n1,mickey,mouse\n2,minnie,mouse\n3,donald,duck\n"

# read and parse the data
csv_in = CSV.new(data, :headers => true)

# open the temp file
CSV.open('./temp.csv', 'w') do |csv_out|

# output the headers embedded in the object, then rewind to the start of the list
csv_out << csv_in.first.headers
csv_in.rewind

# loop over the rows
csv_in.each do |row|

# munge the first name
if (row['FName']['mi'])
row['FName'] = row['FName'][1 .. -1] << '-' << row['FName'][0] << 'ay'
end

# output the record
csv_out << row.fields
end
end

The output looks like:

ID,FName,LName
1,ickey-may,mouse
2,innie-may,mouse
3,donald,duck

How to find and replace element in CSV

You can't use the CSV class to read this because it's a malformed CSV string. Sometimes that happens because whoever generated it didn't know what they were doing:

require 'csv'
foo = '"LastName","FirstName","","","890","","6G","","S "West" AVENUE","","CITY","ZIP"'
arr_of_arrs = CSV.parse(foo)

Which then results in an exception:

Missing or stray quote in line 1 (CSV::MalformedCSVError)

Instead, to deal with this, you have to fix up the data, then parse. Here's a starting point:

/(?<=\s)("[^"]+")(?=\s)/

http://rubular.com/r/sWEkx07Zyo

The pattern is looking for something between quotes, wrapped with leading and trailing spaces. The spaces are not captured.

Here's some code that'd work for this particular example:

foo = '"LastName","FirstName","","","890","","6G","","S "West" AVENUE","","CITY","ZIP"'

REGEX = /(?<=\s)("[^"]+")(?=\s)/

word = foo[REGEX]
foo[REGEX] = word[1..-2]
puts foo
# >> "LastName","FirstName","","","890","","6G","","S West AVENUE","","CITY","ZIP"

At this point CSV could be used:

require 'csv'
arr_of_arrs = CSV.parse(foo)
# => [["LastName",
# "FirstName",
# "",
# "",
# "890",
# "",
# "6G",
# "",
# "S West AVENUE",
# "",
# "CITY",
# "ZIP"]]

This stuff might be confusing:

word = foo[REGEX]
foo[REGEX] = word[1..-2]

foo\[...\] is part of the String class, and is a nice and convenient way to find and replace characters in a string.


It's possible to get the CSV parser to be happy with the embedded quotes though, so if throwing them away is too heavy handed, you can do something like:

word = foo[REGEX]
foo[REGEX] = '"%s"' % word

require 'csv'
arr_of_arrs = CSV.parse(foo)
# => [["LastName",
# "FirstName",
# "",
# "",
# "890",
# "",
# "6G",
# "",
# "S \"West\" AVENUE",
# "",
# "CITY",
# "ZIP"]]

Which simply plays by the CSV spec's rules and uses doubled double-quotes around the string.

set column width while generating CSV using fastercsv

You can't. CSV doesn't have formatting metadata.

How would you replace the headers in a CSV file?

You don't even need to do this with the CSV library. Just change the first line of the file, output the rest the same:

lines = File.readlines(@filename)
lines.shift
lines.unshift(["herp", "derp", "herpaderp"].join(',') + "\n")
puts lines.join('')

Export to csv using FasterCSV causes strange punctuation characters

Word documents are not text documents. Things like smart-quotes, non-ASCII quotes, accented characters, etc. obviously get messed up. I'm not even sure if it's just a matter of UTF-8 encoding, although you could try that first--see this for more info. FasterCSV supports Ruby 1.9 encoding vi the :encoding option.

Personally, I tend to just tell people to not do that, and use an actual text editor, but that isn't always an option.

Having issues importing a CSV File using FasterCSV

Issue is resolved thanks to James Gray

  def csv_import
file = params[:file]
FCSV.new(file.tempfile, :headers => true).each do |row|
Script.create!(:name => row[0],
:task => row[1],
:expected_results => row[2],
:require_id => row[3],
:department_id => 1,
:category_id => 1)
end
end

how to check the csv contain a specific column header in ruby using fastercsv

I think you can read the content of csv file with this:

FasterCSV.foreach("path/to/file.csv") do |row|
# use row here...
end

than you can use header? and headers() methods to determine headers. Vizit http://fastercsv.rubyforge.org/ if you need additional information.

Write value to CSV Column with RUBY

Short answer is you cannot (that is, you still need to iterate through the whole file and write out another one). For The longer version, please see here.



Related Topics



Leave a reply



Submit