BEGINNER - Convert csv file to tsv

Hi,

I am a beginner at Ruby, but I am trying to convert a csv file into a
tsv file.

The data is stored in source.csv and I need to out put it to a file in
the same directory called source.tsv, I also need to cater to output to
.txt and .xml, but starting with tsv first.

Contents of source.csv
“Firstname”,“Lastname”,“Postcode”
“John”,“Smith”,“EC1”
“Paula”,“James”,“NE13”

Output to file source.tsv
Firstname Lastname Postcode
John Smith EC1
Paula James NE13

I have started with this:

filename = ARGV.first
output_file_format = ARGV.second

file = open(filename, “r+”)
valid_file_formats = [“tsv”]

if output_file_format == “tsv”
File.open (filename, “r”) do |f|
new_file = File.open(“source.tsv”, “w”)
f.each_line do |line|
fields = line.split (“”\n")
fields.each { |fd| fd = “"#{fd}"”
new_file.write(fields.join(“,”)
end
new_file.close
end

I understand what I need to do in my head, for each line remove the " or
, characters and replace the , character with a tab (\t), but I am
struggling with the syntax.

Using a bit of help from Converting CSV - Ruby - Ruby-Forum

Thanks in advance

On Wed, Apr 24, 2013 at 10:45 AM, Jon R. [email protected] wrote:

Contents of source.csv

new_file = File.open("source.tsv", "w")

, characters and replace the , character with a tab (\t), but I am
struggling with the syntax.

Using a bit of help from Converting CSV - Ruby - Ruby-Forum

Thanks in advance

I would use the csv in the stdlib to parse the csv:

http://www.ruby-doc.org/stdlib-2.0/libdoc/csv/rdoc/index.html

Jesus.

there is a lib in stdlib for parsing csv:

require “csv”

File.open(“tmp.tsv”,“w”) {|out|
CSV.foreach(“tmp.csv”) {|l|
out.write(l.join("\t")+"\n")
}
}

I wanted to try and use ruby rather than a library

On Wed, Apr 24, 2013 at 4:00 AM, Hans M. [email protected]
wrote:


Posted via http://www.ruby-forum.com/.

Here’s a one-liner:

ruby -r csv -e ‘CSV.filter(File.open(“input.csv”,“r”),
File.open(“output.tsv”,“w”), :output_col_sep => “\t”){|row| row}’

Jon R. wrote in post #1106750:

I wanted to try and use ruby rather than a library

Here’s an example without using CSV:

File.write( ‘source.tsv’, File.readlines( ‘source.csv’ ).map do |l|
l.chomp.gsub( /^"|"$/, ‘’ ).gsub( /","/, “\t” )
end.join("\n") )

On Wed, Apr 24, 2013 at 11:00 AM, Hans M.
[email protected]wrote:

there is a lib in stdlib for parsing csv:

require “csv”

File.open(“tmp.tsv”,“w”) {|out|
CSV.foreach(“tmp.csv”) {|l|
out.write(l.join(“\t”)+“\n”)
}
}

That’s kind of inconsequent, isn’t it? You use a CSV lib for reading
but
not for writing. That way you miss good things like quoting.

I almost like tamouse’s solution best - if it wasn’t for the missing
stream
closing. To me the most straightforward would probably be:

CSV.open(“source.tsv”, “wb”, col_sep: “\t”) do |cout|
CSV.foreach(“source.csv”, col_sep: “,”) do |r|
cout << r
end
end

Or, with CSV::filter:

File.open(“source.csv”) do |cin|
File.open(“source.tsv”, “w”) do |cout|
CSV.filter(cin, cout, output_col_sep:“\t”) {|r| r}
end
end

Btw. I think that CSV.filter should also work without a block and then
should use it unmodified.

Kind regards

robert