summaryrefslogtreecommitdiff
path: root/doc/csv/recipes/filtering.rdoc
blob: 1552bf0fb86658c475cc05b72ad27800e1315d18 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
== Recipes for Filtering \CSV

These recipes are specific code examples for specific \CSV filtering tasks.

For other recipes, see {Recipes for CSV}[./recipes_rdoc.html].

All code snippets on this page assume that the following has been executed:
  require 'csv'

=== Contents

- {Source and Output Formats}[#label-Source+and+Output+Formats]
  - {Filtering String to String}[#label-Filtering+String+to+String]
    - {Recipe: Filter String to String with Headers}[#label-Recipe-3A+Filter+String+to+String+with+Headers]
    - {Recipe: Filter String to String Without Headers}[#label-Recipe-3A+Filter+String+to+String+Without+Headers]
  - {Filtering String to IO Stream}[#label-Filtering+String+to+IO+Stream]
    - {Recipe: Filter String to IO Stream with Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+with+Headers]
    - {Recipe: Filter String to IO Stream Without Headers}[#label-Recipe-3A+Filter+String+to+IO+Stream+Without+Headers]
  - {Filtering IO Stream to String}[#label-Filtering+IO+Stream+to+String]
    - {Recipe: Filter IO Stream to String with Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+with+Headers]
    - {Recipe: Filter IO Stream to String Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+String+Without+Headers]
  - {Filtering IO Stream to IO Stream}[#label-Filtering+IO+Stream+to+IO+Stream]
    - {Recipe: Filter IO Stream to IO Stream with Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+with+Headers]
    - {Recipe: Filter IO Stream to IO Stream Without Headers}[#label-Recipe-3A+Filter+IO+Stream+to+IO+Stream+Without+Headers]

=== Source and Output Formats

You can use a Unix-style "filter" for \CSV data.
The filter reads source \CSV data and writes output \CSV data as modified by the filter.
The input and output \CSV data may be any mixture of \Strings and \IO streams.

==== Filtering \String to \String

You can filter one \String to another, with or without headers.

===== Recipe: Filter \String to \String with Headers

Use class method CSV.filter with option +headers+ to filter a \String to another \String:
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
  out_string = ''
  CSV.filter(in_string, out_string, headers: true) do |row|
    row[0] = row[0].upcase
    row[1] *= 4
  end
  out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"

===== Recipe: Filter \String to \String Without Headers

Use class method CSV.filter without option +headers+ to filter a \String to another \String:
  in_string = "foo,0\nbar,1\nbaz,2\n"
  out_string = ''
  CSV.filter(in_string, out_string) do |row|
    row[0] = row[0].upcase
    row[1] *= 4
  end
  out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"

==== Filtering \String to \IO Stream

You can filter a \String to an \IO stream, with or without headers.

===== Recipe: Filter \String to \IO Stream with Headers

Use class method CSV.filter with option +headers+ to filter a \String to an \IO stream:
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
  path = 't.csv'
  File.open(path, 'w') do |out_io|
    CSV.filter(in_string, out_io, headers: true) do |row|
      row[0] = row[0].upcase
      row[1] *= 4
    end
  end
  p File.read(path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"

===== Recipe: Filter \String to \IO Stream Without Headers

Use class method CSV.filter without option +headers+ to filter a \String to an \IO stream:
  in_string = "foo,0\nbar,1\nbaz,2\n"
  path = 't.csv'
  File.open(path, 'w') do |out_io|
    CSV.filter(in_string, out_io) do |row|
      row[0] = row[0].upcase
      row[1] *= 4
    end
  end
  p File.read(path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n"

==== Filtering \IO Stream to \String

You can filter an \IO stream to a \String, with or without headers.

===== Recipe: Filter \IO Stream to \String with Headers

Use class method CSV.filter with option +headers+ to filter an \IO stream to a \String:
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
  path = 't.csv'
  File.write(path, in_string)
  out_string = ''
  File.open(path, headers: true) do |in_io|
    CSV.filter(in_io, out_string, headers: true) do |row|
      row[0] = row[0].upcase
      row[1] *= 4
    end
  end
  out_string # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"

===== Recipe: Filter \IO Stream to \String Without Headers

Use class method CSV.filter without option +headers+ to filter an \IO stream to a \String:
  in_string = "foo,0\nbar,1\nbaz,2\n"
  path = 't.csv'
  File.write(path, in_string)
  out_string = ''
  File.open(path) do |in_io|
    CSV.filter(in_io, out_string) do |row|
      row[0] = row[0].upcase
      row[1] *= 4
    end
  end
  out_string # => "FOO,0000\nBAR,1111\nBAZ,2222\n"

==== Filtering \IO Stream to \IO Stream

You can filter an \IO stream to another \IO stream, with or without headers.

===== Recipe: Filter \IO Stream to \IO Stream with Headers

Use class method CSV.filter with option +headers+ to filter an \IO stream to another \IO stream:
  in_path = 't.csv'
  in_string = "Name,Value\nfoo,0\nbar,1\nbaz,2\n"
  File.write(in_path, in_string)
  out_path = 'u.csv'
  File.open(in_path) do |in_io|
    File.open(out_path, 'w') do |out_io|
      CSV.filter(in_io, out_io, headers: true) do |row|
        row[0] = row[0].upcase
        row[1] *= 4
      end
    end
  end
  p File.read(out_path) # => "Name,Value\nFOO,0000\nBAR,1111\nBAZ,2222\n"

===== Recipe: Filter \IO Stream to \IO Stream Without Headers

Use class method CSV.filter without option +headers+ to filter an \IO stream to another \IO stream:
  in_path = 't.csv'
  in_string = "foo,0\nbar,1\nbaz,2\n"
  File.write(in_path, in_string)
  out_path = 'u.csv'
  File.open(in_path) do |in_io|
    File.open(out_path, 'w') do |out_io|
      CSV.filter(in_io, out_io) do |row|
        row[0] = row[0].upcase
        row[1] *= 4
      end
    end
  end
  p File.read(out_path) # => "FOO,0000\nBAR,1111\nBAZ,2222\n"