# Csv updater

**URL:** <https://www.ruby-forum.com/t/csv-updater/82933>\
**Category:** Ruby\
**Created:** [March 17, 2006, 12:30am UTC](https://www.ruby-forum.com/t/csv-updater/82933 "2006-03-17T00:30:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![geoff](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/a3d4f5/32.png) [@geoff](https://www.ruby-forum.com/u/geoff)\
**Post date:** [March 17, 2006, 12:30am UTC](https://www.ruby-forum.com/t/csv-updater/82933/1 "2006-03-17T00:30:21Z")

</div>

Greetings!

I got some help on this a while back and have been tweaking on it  
trying to get it do work right. What I want to do is take a csv file,  
and whenever there is a blank cell update it with the info from the  
cell directly above (and on down as long as there are blanks).

There are two problems with what I have so far:

1. It does not retain the double quotes and I would like it to be able  
to do that.
2. On a previous version it was working for just the last column. I  
have tried to adjust it to make it work for any column (at least that I  
list in the write(colNum) definition, but it is not working.

\<\>

require ‘CSV’

class BlankFiller  
def initialize(last=’’)  
@last = last  
end

```
def fill(e)
	if e.empty?
		e = @last
	else
		@last = e
	end
end

```

end

blank\_filler = BlankFiller.new  
out\_csv = CSV.open(‘C:\temp\geoff\filldown\filldownNew.txt’, ‘w’)

class ColumnWrite \< BlankFiller  
def write(colNum)  
CSV.foreach(“C:\temp\geoff\filldown\filldown.txt”) do |row|  
row[colNum] = blank\_filler.fill(row[colNum])  
out\_csv \<\< row  
end  
write(0)  
write(1)  
write(2)  
end  
end

\<\>

Here is the csv file I’m working with for a test case:

“BegDoc”,“EndDoc”,“New”  
“Doc1BegDoc”,“Doc1EndDoc”,“Test1”  
“Doc2BegDoc”,"",""  
“Doc2BegDoc”,"",""  
“Doc3BegDoc”,“Doc3EndDoc”,“Test2”  
“Doc4BegDoc”,"",""  
“Doc5BegDoc”,“Doc5EndDoc”,“New”

Ideas?

Thanks!

Geoff

---

<div class="post-metadata">

**Author:** ![geoff](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/a3d4f5/32.png) [@geoff](https://www.ruby-forum.com/u/geoff)\
**Post date:** [March 17, 2006, 5:50am UTC](https://www.ruby-forum.com/t/csv-updater/82933/2 "2006-03-17T05:50:59Z")

</div>

On Mar 16, 2006, at 5:28 PM, Geoff wrote:

> 1. It does not retain the double quotes and I would like it to be able  
> to do that.
> 2. On a previous version it was working for just the last column. I  
> have tried to adjust it to make it work for any column (at least  
> that I  
> list in the write(colNum) definition, but it is not working.

I’m pretty sure this does what you want:

Neo:~/Desktop$ ls  
csv\_filldown.rb test\_data.csv  
Neo:~/Desktop$ cat test\_data.csv  
“BegDoc”,“EndDoc”,“New”  
“Doc1BegDoc”,“Doc1EndDoc”,“Test1”  
“Doc2BegDoc”,"",""  
“Doc2BegDoc”,"",""  
“Doc3BegDoc”,“Doc3EndDoc”,“Test2”  
“Doc4BegDoc”,"",""  
“Doc5BegDoc”,“Doc5EndDoc”,“New”  
Neo:~/Desktop$ cat csv\_filldown.rb  
#!/usr/local/bin/ruby -w

require “csv”  
require “enumerator”

last\_row = Array.new

CSV.foreach(ARGV.shift) do |row|  
puts( row.enum\_for(:each\_with\_index).map do |cell, index|  
if cell.empty?  
last\_row[index]  
else  
last\_row[index] = cell  
end  
end.map { |output| “”#{output}""}.join(",") )  
end  
Neo:~/Desktop$ ruby csv\_filldown.rb test\_data.csv \> output.csv  
Neo:~/Desktop$ cat output.csv  
“BegDoc”,“EndDoc”,“New”  
“Doc1BegDoc”,“Doc1EndDoc”,“Test1”  
“Doc2BegDoc”,“Doc1EndDoc”,“Test1”  
“Doc2BegDoc”,“Doc1EndDoc”,“Test1”  
“Doc3BegDoc”,“Doc3EndDoc”,“Test2”  
“Doc4BegDoc”,“Doc3EndDoc”,“Test2”  
“Doc5BegDoc”,“Doc5EndDoc”,“New”

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![geoff](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/a3d4f5/32.png) [@geoff](https://www.ruby-forum.com/u/geoff)\
**Post date:** [March 17, 2006, 6:40pm UTC](https://www.ruby-forum.com/t/csv-updater/82933/3 "2006-03-17T18:40:30Z")

</div>

Cool, the puts command works, but when I tweak it to output this to a  
file, the result is:

78,101,119  
84,101,115,116,49  
84,101,115,116,49  
84,101,115,116,49  
84,101,115,116,50  
84,101,115,116,50  
78,101,119

The tweak I used on the code is:

require “csv”  
require “enumerator”

last\_row = Array.new  
out\_csv = CSV.open(“C:\temp\geoff\filldown\filldownNew.txt”, “w”)  
output = ‘’  
CSV.foreach(“C:\temp\geoff\filldown\filldown.txt”) do |row|  
puts( row.enum\_for(:each\_with\_index).map do |cell, index|  
if cell.empty?  
last\_row[index]  
else  
last\_row[index] = cell  
end  
end.map { |output| “”#{output}""}.join(",") )  
out\_csv \<\< output  
end

I’m getting the feeling I just don’t understand programming and Ruby  
enough at this point and need to re-read some intro material. Thanks a  
bunch for spending time on this problem for me, I do appreciate it!

---

<div class="post-metadata">

**Author:** ![geoff](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/a3d4f5/32.png) [@geoff](https://www.ruby-forum.com/u/geoff)\
**Post date:** [March 17, 2006, 7:41pm UTC](https://www.ruby-forum.com/t/csv-updater/82933/4 "2006-03-17T19:41:48Z")

</div>

> > If you go back and look at my last message, I used the puts version  
> > to create a file (using redirection). That’s a pretty flexible  
> > trick, probably worth getting the hang of.

I’ll have to look into that. When I run that code it does not modify my  
file, just puts to the shell. Sounds like a good trick, which I’ll  
certainly look into.

> > The main problem with your new version is that you are using CSV to  
> > manage the output file, but it order to enforce quoting we had to  
> > roll our own solution (the CSV file format does not require it for  
> > the examples you are showing). Switching to a normal file should get  
> > you going:

Ah… works perfectly!

Thanks a ton for your help on this! I think I’ve learned more by trying  
to solve this problem than I have the whole time reading tutorials and  
such.

Geoff

---

<div class="post-metadata">

**Author:** ![geoff](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/a3d4f5/32.png) [@geoff](https://www.ruby-forum.com/u/geoff)\
**Post date:** [March 17, 2006, 7:22pm UTC](https://www.ruby-forum.com/t/csv-updater/82933/5 "2006-03-17T19:22:46Z")

</div>

On Mar 17, 2006, at 11:38 AM, Geoff wrote:

> Cool, the puts command works, but when I tweak it to output this to a  
> file…

If you go back and look at my last message, I used the puts version  
to create a file (using redirection). That’s a pretty flexible  
trick, probably worth getting the hang of.

The main problem with your new version is that you are using CSV to  
manage the output file, but it order to enforce quoting we had to  
roll our own solution (the CSV file format does not require it for  
the examples you are showing). Switching to a normal file should get  
you going:

#!/usr/local/bin/ruby -w

require “csv”  
require “enumerator”

last\_row = Array.new

File.open(“C:\temp\geoff\filldown\filldownNew.txt”, “w”) do |  
out\_file|  
CSV.foreach(“C:\temp\geoff\filldown\filldown.txt”) do |row|  
out\_file.puts( row.enum\_for(:each\_with\_index).map do |cell, index|  
if cell.empty?  
last\_row[index]  
else  
last\_row[index] = cell  
end  
end.map { |output| “”#{output}""}.join(",") )  
end  
end

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![geoff](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/a3d4f5/32.png) [@geoff](https://www.ruby-forum.com/u/geoff)\
**Post date:** [March 17, 2006, 7:51pm UTC](https://www.ruby-forum.com/t/csv-updater/82933/6 "2006-03-17T19:51:15Z")

</div>

On Mar 17, 2006, at 12:38 PM, Geoff wrote:

> I’ll have to look into that. When I run that code it does not  
> modify my  
> file, just puts to the shell. Sounds like a good trick, which I’ll  
> certainly look into.

It depends on how you run it:

ruby csv\_filldown.rb # \<= this just prints to the screen

ruby csv\_filldown.rb \> output.csv # redirected to a file

> Thanks a ton for your help on this! I think I’ve learned more by  
> trying  
> to solve this problem than I have the whole time reading tutorials and  
> such.

Happy to help.

James Edward G. II
