How to remove a row from a CSV with Ruby

13,190

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.

Share:
13,190
spuder
Author by

spuder

Automation Engineer Deving all of the Ops in Lehi, Utah. Primarily focused in: Puppet Chef Docker #SOreadytohelp

Updated on June 04, 2022

Comments

  • spuder
    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 a delete_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