Ruby-esque approaches to adding a line at the beginning of a file

On our local lug mail list a discussion came up about using Ruby (as opposed
to Perl) for an application that involved inserting a new line at the front
of an existing file.

(As a newbie), I proposed an approach like this (with help from the Ruby
Cookbook which I'm working my way through).

t = "New first line of file.\n"
t = t + open("sample_file") { |f| f.read }
open("sample_file", "w") { |f| f.write(t)}

However, it doesn't appear (to me) to be very Ruby-esque--I'm wondering how
others on this list might approach such a task.

Randy Kramer

I think it's as good as anything. You could scrunch it up a bit like this:

     t = "New First Line\n" + File.read("sample_file")
     ...

--Steve

···

On Mar 26, 2006, at 12:55 PM, Randy Kramer wrote:

t = "New first line of file.\n"
t = t + open("sample_file") { |f| f.read }
open("sample_file", "w") { |f| f.write(t)}

However, it doesn't appear (to me) to be very Ruby-esque--I'm wondering how
others on this list might approach such a task.

If the intention is to do it in the command line, you can write:

ruby -i -pe 'puts "New first line" if ARGF.file.lineno == 1' file

and that will work even with multiple files

···

2006/3/26, Randy Kramer <rhkramer@gmail.com>:

On our local lug mail list a discussion came up about using Ruby (as opposed
to Perl) for an application that involved inserting a new line at the front
of an existing file.

(As a newbie), I proposed an approach like this (with help from the Ruby
Cookbook which I'm working my way through).

t = "New first line of file.\n"
t = t + open("sample_file") { |f| f.read }
open("sample_file", "w") { |f| f.write(t)}

However, it doesn't appear (to me) to be very Ruby-esque--I'm wondering how
others on this list might approach such a task.

Randy Kramer

--
Gerardo Santana
"Between individuals, as between nations, respect for the rights of
others is peace" - Don Benito Juárez

Well, assuming reading the entire file into memory is acceptable,
we can use a fairly standard approach without a temporary file:

  #!/usr/bin/ruby -w

  file = 'somefile'
  first = "new start\n"

  File.open(file,'r+') do |f|
    contents = f.read
    f.seek 0, IO::SEEK_SET
    f.truncate 0
    f.puts first, contents
  end

And, if you like, you can wrap the manipulations with #flock

  File.open(file,'r+') do |f|
    f.flock File::LOCK_EX
    contents = f.read
    f.seek 0, IO::SEEK_SET
    f.truncate 0
    f.puts first, contents
    f.flock File::LOCK_UN
  end

Of course, this is a generalized version for any content manipulation you
might want to do on the contents, not just adding a new first line.

Otherwise, loop over lines, making changes and writing to a temp file, and
afterwards, #rename the temp file back to the original.

Or, use the command line -i switch:

  $ cat somefile
  one
  two
  three

  $ ruby -pi -e 'puts "zero\n" if $. == 1' somefile

  $ cat somefile
  zero
  one
  two
  three

regards,
andrew

···

On Mon, 27 Mar 2006 05:55:30 +0900, Randy Kramer <rhkramer@gmail.com> wrote:

On our local lug mail list a discussion came up about using Ruby (as opposed
to Perl) for an application that involved inserting a new line at the front
of an existing file.

--
Andrew L. Johnson http://www.siaris.net/
      What have you done to the cat? It looks half-dead.
          -- Schroedinger's wife