Wayne Conrad Wayne Conrad - 6 months ago 17
Ruby Question

How to write DOS line endings to a file from Unix

My Unix Ruby program needs to write a file that will be read by
SqlServer running on Windows. I need for the lines I write to this
file to end in

\r\n
, the DOS/Windows line ending, rather than
\n
,
the Unix line ending. I want this to happen without me having to
manually add the \r to the end of each line.

The starting point



If my program writes to the file like this:

File.open("/tmp/foo", "w") do |file|
file.puts "stuff"
end


Then the file has Unix line endings:

$ od -c foo
0000000 s t u f f \n


That is expected, since my program is running on Unix. But I
need for this file (and this file only) to have DOS line endings.

Adding the \r to each line manually



If I add the \r to each line manually:

File.open("/tmp/foo", "w") do |file|
file.puts "stuff\r"
end


Then the file has DOS line endings:

$ od -c /tmp/foo
0000000 s t u f f \r \n


This works, but has to be repeated for each line I want to write.

Using String#encode



As shown by this SO answer, I can modify the string using
String#encode before writing it:

File.open("/tmp/foo", "w") do |file|
file.puts "alpha\nbeta\n".encode(crlf_newline: true)
end


This results in DOS line endings:

$ od -c /tmp/foo
0000000 a l p h a \r \n b e t a \r \n


This has the advantage that if I am writing multiple lines at once,
one call to #encode will change all the line endings for that one
write. However, it's verbose, and I still have to specify the line
ending for every write.

How can I cause each
puts
to an open file in Unix to end
the line in the Windows
\r\n
line ending rather than the Unix '\n'
line ending?


I am running Ruby 2.3.1.

Answer

There's an option for this, the same one you're using on encode also works with File.open:

File.open('/tmp/foo', mode: 'w', crlf_newline: true) do |file|
  file.puts("alpha")
  file.puts("beta")
end

This option not only ends lines in \r\n, it also translates any explicit \n into \r\n. So this:

file.puts("alpha\nbar")

will write alpha\r\nbar\r\b

Comments