Install the CSV gem
mainTo use the CSV library in your Ruby application, add it to your Gemfile and run bundle.
Alternatively, you can install the gem directly from your terminal using gem install csv.
gem 'csv'repository·main·Indexed 42 days ago
https://github.com/ruby/csvA complete interface for reading and writing CSV (Comma-Separated Values) data in Ruby. It supports working with Strings and IO objects, providing methods like CSV.foreach for memory-efficient iteration, CSV.parse for string conversion, and CSV.generate for creating CSV data. The library includes support for headers, field and header converters (such as :integer, :float, and :symbol), and custom options for separators and quoting.
To use the CSV library in your Ruby application, add it to your Gemfile and run bundle.
Alternatively, you can install the gem directly from your terminal using gem install csv.
gem 'csv'A CSV::Parser is multi-language (m17n) aware. The parser operates within the Encoding of the IO or String object being read.
Key behaviors:
CSV returns Arrays or Rows containing Strings in the same encoding as the source data.When parsing CSV data with headers, you can either specify headers: true (to use the first row of the data as headers) or provide an array of header names via the headers option. When headers are used, parsing methods return a CSV::Table object containing CSV::Row objects instead of plain Arrays.
# Headers are part of the data
data = CSV.parse(<<~ROWS, headers: true)
Name,Department,Salary
Bob,Engineering,1000
Jane,Sales,2000
ROWS
data.class #=> CSV::Table
data.first #=> #<CSV::Row "Name":"Bob" "Department":"Engineering" "Salary":"1000">
data.first.to_h #=> {"Name"=>"Bob", "Department"=>"Engineering", "Salary"=>"1000"}
# Headers provided manually
data = CSV.parse('Bob,Engineering,1000', headers: %i[name department salary])Header converters transform the header names during parsing. Use the header_converters option with a Proc, a symbol, or a list. These are stored in CSV::HeaderConverters.
# Using built-in :downcase
CSV.parse(string, headers: true, header_converters: :downcase)
# Using built-in :symbol (strips whitespace, downcases, replaces spaces with underscores)
CSV.parse(string, headers: true, header_converters: :symbol)
# Using a custom Proc
upcase_converter = proc {|header| header.upcase }
CSV.parse(string, headers: true, header_converters: upcase_converter)Field converters intercept parsed values and transform them before they are returned. You can pass a Proc, a symbol representing a built-in converter, or an array of both to the converters option.
# Using a built-in converter
CSV.parse(string, converters: :integer)
# Using a custom Proc converter
strip_converter = proc {|field| field.strip }
CSV.parse(string, converters: strip_converter)
# Using a converter list
CSV.parse(string, converters: [:integer, :float])
# Registering and using a custom named converter
CSV::Converters[:strip] = proc {|field| field.strip }
CSV.parse(string, converters: :strip)A CSV::Table instance can operate in three different modes, which change how indexing and iteration behave. The mode determines whether [], []=, delete, delete_if, each, and values_at act on rows or columns.
:row): Accessing by an Integer index returns a CSV::Row. Accessing by a Range returns an array of CSV::Row objects.:col): Accessing by an Integer index returns an Array of column data. Accessing by a String header returns an Array of column data.:col_or_row): This is the default mode. It allows dual access: Integer or Range indices refer to rows, while String indices refer to columns.You can switch modes in-place using bang methods (e.g., by_row!) or create a duplicate in a specific mode using non-bang methods (e.g., by_row).
source = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
table = CSV.parse(source, headers: true)
# Switch to row mode in-place
table.by_row!
table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
# Switch to column mode in-place
table.by_col!
table['Name'] # => ["foo", "bar", "baz"]
# Switch to mixed mode (default)
table.by_col_or_row!
table[1] # => #<CSV::Row "Name":"bar" "Value":"1">
table['Name'] # => ["foo", "bar", "baz"]CSV::Parser is multi-lingual (m17n) aware. It operates using the encoding of the IO or String object being read. Data is parsed in its original encoding without automatic transcoding unless explicitly requested via Ruby's transcoding mechanisms. Consequently, the resulting Arrays or Rows of Strings will maintain the encoding of the source data.Write converters allow you to modify values just before they are written to the CSV output. Use the write_converters option in CSV.generate or when creating a new CSV instance.
strip_converter = proc {|field| field.respond_to?(:strip) ? field.strip : field }
upcase_converter = proc {|field| field.respond_to?(:upcase) ? field.upcase : field }
output_string = CSV.generate(write_converters: [strip_converter, upcase_converter]) do |csv|
csv << [' foo ', 0]
end
# => "FOO,0\n"The CSV.foreach method is the standard way to iterate over a CSV file. It reads the file one row at a time, which is memory-efficient for large files. The block yields a row object for each line in the file.
require "csv"
CSV.foreach("path/to/file.csv") do |row|
# use row here...
endYou can specify the characters used to delimit columns and rows:
column_separator (or col_sep): The character(s) separating fields. Must be 1 or more characters.row_separator (or row_sep): The character(s) separating rows. Setting this to :auto enables automatic detection of line endings (e.g., `,
, or
`).
The skip_lines option allows you to skip rows that match a specific pattern. It accepts:
String: Rows containing this string will be skipped.Regexp: Rows matching this regular expression will be skipped.#match.The liberal_parsing option allows for more relaxed CSV parsing. It can be passed as a boolean or a Hash to control specific behaviors:
liberal_parsing: true: Enables general liberal parsing.liberal_parsing: { double_quote_outside_quote: true }: Allows double quotes to appear outside of quoted fields (they will be treated as part of the data).liberal_parsing: { backslash_quote: true }: Enables backslash escaping for quotes.