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
Why Doesn't 'User Installation Directory' Match with the Ruby Version
Best Practice to Mark Deprecated Code in Ruby
Ruby Working on Array Elements in Groups of Four
Accessing Config from Application.Rb in Controller (Rails 3)
Can Someone Explain Ruby's Use of Pipe Characters in a Block
Rails - Invalid Authenticity Token After Deploy
Is It Idiomatic Ruby to Add an Assert( ) Method to Ruby's Kernel Class
Ruby: How to Iterate Over an Array of Hashes and Return the Values in a Single String
Ruby on Rails Gem for Google Map Integration
How to Make :Level Change Based on :Committed Days
How to Build a Ruby Hash Out of Two Equally-Sized Arrays
When to Use Struct Instead of Hash in Ruby
Ruby's <=> Operator and Sort Method
Setting Up the Logger in Rails 3
Rails-Like Database Migrations