Maintenance Ruby 3.3 gets fixes, but no new features. Switch to Ruby 4.0 →
CSV.filter
# File tmp/rubies/ruby-3.3.0/lib/csv.rb, line 1202
def filter(input=nil, output=nil, **options)
# parse options for input, output, or both
in_options, out_options = Hash.new, {row_sep: InputRecordSeparator.value}
options.each do |key, value|
case key
when /\Ain(?:put)?_(.+)\Z/
in_options[$1.to_sym] = value
when /\Aout(?:put)?_(.+)\Z/
out_options[$1.to_sym] = value
else
in_options[key] = value
out_options[key] = value
end
end
# build input and output wrappers
input = new(input || ARGF, **in_options)
output = new(output || $stdout, **out_options)
# process headers
need_manual_header_output =
(in_options[:headers] and
out_options[:headers] == true and
out_options[:write_headers])
if need_manual_header_output
first_row = input.shift
if first_row
if first_row.is_a?(Row)
headers = first_row.headers
yield headers
output << headers
end
yield first_row
output << first_row
end
end
# read, yield, write
input.each do |row|
yield row
output << row
end
end
-
Parses CSV from a source (String, IO stream, or
ARGF). -
Calls the given block with each parsed row:
-
Without headers, each row is an Array.
-
With headers, each row is a
CSV::Row.
-
-
Generates CSV to an output (String, IO stream, or STDOUT).
-
Returns the parsed source:
-
Without headers, an Array of Arrays.
-
With headers, a
CSV::Table.
-
When in_string_or_io is given, but not out_string_or_io, parses from the given in_string_or_io and generates to STDOUT.
String input without headers:
in_string = "foo,0\nbar,1\nbaz,2" CSV.filter(in_string) do |row| row[0].upcase! row[1] = - row[1].to_i end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]]
Output (to STDOUT):
FOO,0 BAR,-1 BAZ,-2
String input with headers:
in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" CSV.filter(in_string, headers: true) do |row| row[0].upcase! row[1] = - row[1].to_i end # => #<CSV::Table mode:col_or_row row_count:4>
Output (to STDOUT):
Name,Value FOO,0 BAR,-1 BAZ,-2
IO stream input without headers:
File.write('t.csv', "foo,0\nbar,1\nbaz,2") File.open('t.csv') do |in_io| CSV.filter(in_io) do |row| row[0].upcase! row[1] = - row[1].to_i end end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]]
Output (to STDOUT):
FOO,0 BAR,-1 BAZ,-2
IO stream input with headers:
File.write('t.csv', "Name,Value\nfoo,0\nbar,1\nbaz,2") File.open('t.csv') do |in_io| CSV.filter(in_io, headers: true) do |row| row[0].upcase! row[1] = - row[1].to_i end end # => #<CSV::Table mode:col_or_row row_count:4>
Output (to STDOUT):
Name,Value FOO,0 BAR,-1 BAZ,-2
When both in_string_or_io and out_string_or_io are given, parses from in_string_or_io and generates to out_string_or_io.
String output without headers:
in_string = "foo,0\nbar,1\nbaz,2" out_string = '' CSV.filter(in_string, out_string) do |row| row[0].upcase! row[1] = - row[1].to_i end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] out_string # => "FOO,0\nBAR,-1\nBAZ,-2\n"
String output with headers:
in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" out_string = '' CSV.filter(in_string, out_string, headers: true) do |row| row[0].upcase! row[1] = - row[1].to_i end # => #<CSV::Table mode:col_or_row row_count:4> out_string # => "Name,Value\nFOO,0\nBAR,-1\nBAZ,-2\n"
IO stream output without headers:
in_string = "foo,0\nbar,1\nbaz,2" File.open('t.csv', 'w') do |out_io| CSV.filter(in_string, out_io) do |row| row[0].upcase! row[1] = - row[1].to_i end end # => [["FOO", 0], ["BAR", -1], ["BAZ", -2]] File.read('t.csv') # => "FOO,0\nBAR,-1\nBAZ,-2\n"
IO stream output with headers:
in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2" File.open('t.csv', 'w') do |out_io| CSV.filter(in_string, out_io, headers: true) do |row| row[0].upcase! row[1] = - row[1].to_i end end # => #<CSV::Table mode:col_or_row row_count:4> File.read('t.csv') # => "Name,Value\nFOO,0\nBAR,-1\nBAZ,-2\n"
When neither in_string_or_io nor out_string_or_io given, parses from ARGF and generates to STDOUT.
Without headers:
# Put Ruby code into a file. ruby = <<-EOT require 'csv' CSV.filter do |row| row[0].upcase! row[1] = - row[1].to_i end EOT File.write('t.rb', ruby) # Put some CSV into a file. File.write('t.csv', "foo,0\nbar,1\nbaz,2") # Run the Ruby code with CSV filename as argument. system(Gem.ruby, "t.rb", "t.csv")
Output (to STDOUT):
FOO,0 BAR,-1 BAZ,-2
With headers:
# Put Ruby code into a file. ruby = <<-EOT require 'csv' CSV.filter(headers: true) do |row| row[0].upcase! row[1] = - row[1].to_i end EOT File.write('t.rb', ruby) # Put some CSV into a file. File.write('t.csv', "Name,Value\nfoo,0\nbar,1\nbaz,2") # Run the Ruby code with CSV filename as argument. system(Gem.ruby, "t.rb", "t.csv")
Output (to STDOUT):
Name,Value FOO,0 BAR,-1 BAZ,-2
Arguments:
-
Argument
in_string_or_iomust be a String or an IO stream. -
Argument
out_string_or_iomust be a String or an IO stream. -
Arguments
**optionsmust be keyword options. See Options for Parsing.