How to remove a row from a CSV with Ruby
Solution 1
You should be able to use CSV::Table#delete_if
, but you need to use CSV::table
instead of CSV::read
, because the former will give you a CSV::Table object, whereas the latter results in an Array of Arrays. Be aware that this setting will also convert the headers to symbols.
table = CSV.table(@csvfile)
table.delete_if do |row|
row[:foo] == 'true'
end
File.open(@csvfile, 'w') do |f|
f.write(table.to_csv)
end
Solution 2
You might want to filter rows in a ruby manner:
require 'csv'
csv = CSV.parse(File.read(@csvfile), {
:col_sep => ",",
:headers => true
}
).collect { |item| item[:foo] != 'true' }
Hope it help.
spuder
Automation Engineer Deving all of the Ops in Lehi, Utah. Primarily focused in: Puppet Chef Docker #SOreadytohelp
Updated on June 04, 2022Comments
-
spuder almost 2 years
Given the following CSV file, how would you remove all rows that contain the word 'true' in the column 'foo'?
Date,foo,bar 2014/10/31,true,derp 2014/10/31,false,derp
I have a working solution, however it requires making a secondary CSV object
csv_no_foo
@csv = CSV.read(@csvfile, headers: true) #http://bit.ly/1mSlqfA @headers = CSV.open(@csvfile,'r', :headers => true).read.headers # Make a new CSV @csv_no_foo = CSV.new(@headers) @csv.each do |row| # puts row[5] if row[@headersHash['foo']] == 'false' @csv_no_foo.add_row(row) else puts "not pushing row #{row}" end end
Ideally, I would just remove the offending row from the CSV like so:
... if row[@headersHash['foo']] == 'false' @csv.delete(true) #Doesn't work ...
Looking at the ruby documentation, it looks like the
row
class has adelete_if
function. I'm confused on the syntax that that function requires. Is there a way to remove the row without making a new csv object?http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Row.html#method-i-each