Can one use line addresses...to select a portion of file

I would like to select a portion of a file to process like I did with
sed.

i.e. a file called Menu with the following contents:
__McDonalds__

...
...
...(stuff deleted)

_Happy_Meal__

With sed I would do something like

sed -n "/__McDonalds__/,/__Happy_Meal_/p" Menu

I can not find anything comparable in Ruby. I may be using the wrong
words when I searched google for ruby line address.
Any help will be appreciated.

Thank you,
Raymond

Jacob, Raymond A Jr wrote:

I would like to select a portion of a file to process like I did with
sed.

i.e. a file called Menu with the following contents:
__McDonalds__

...
...
...(stuff deleted)

_Happy_Meal__

With sed I would do something like

sed -n "/__McDonalds__/,/__Happy_Meal_/p" Menu

I can not find anything comparable in Ruby. I may be using the wrong
words when I searched google for ruby line address.
Any help will be appreciated.

Thank you,
Raymond

For a trivial approach, and the most terse one:

lines = file.to_a
lines_to_process = lines[(lines.index("__McDonalds__\n")) ..
lines.index("__Happy_Meal__\n"))]

Requires loading the whole file into memory, can only, and several
passes through it, so the performance is probably ugly, can only handle
lines, and can't cope with regular expressions (which is why you need
the \n in the delimiters). But probably Good Enough for some applications.

A more involved solution would probably be one yielding lines between
lines that match the delimiters to a block or returning an array of them
if no block was given. The most flexible one would be "faking" an IO
object that would start at the starting pattern and then look for the
ending one as it goes, but unless you need the data without line breaks
and without the memory overhead of keeping them in memory, probably too
much bother.

David Vallner

} I would like to select a portion of a file to process like I did with
} sed.
}
} i.e. a file called Menu with the following contents:
} __McDonalds__
}
} ...
} ...
} ...(stuff deleted)
}
} __Happy_Meal__
}
} With sed I would do something like
}
} sed -n "/__McDonalds__/,/__Happy_Meal__/p" Menu
}
} I can not find anything comparable in Ruby. I may be using the wrong
} words when I searched google for ruby line address.
} Any help will be appreciated.

Well, sometimes sed (or awk, which does the same thing even more simply:
awk '/__McDonalds__/,/__Happy_Meal__/') is the right tool. If you are
selected this subset of lines for further processing in ruby, however try
this:

inrange = false
lines = open(file).read.split("\n").select { |line|
  inrange &&= not /__Happy_Meal__/ === line
  inrange ||= /__McDonalds__/ === line
}

} Thank you,
} Raymond
--Greg

···

On Mon, Dec 04, 2006 at 03:19:25AM +0900, Jacob, Raymond A Jr wrote:

Thank you,
Raymond

···

To: Gregory Seidman ] and David Vallner
-----Original Message-----
From: Gregory Seidman [mailto:gsslist+ruby@anthropohedron.net]
Sent: Sunday, December 03, 2006 13:50
To: ruby-talk ML
Subject: Re: Can one use line addresses...to select a portion of file

On Mon, Dec 04, 2006 at 03:19:25AM +0900, Jacob, Raymond A Jr wrote:
} I would like to select a portion of a file to process like I did with
} sed.
}
} i.e. a file called Menu with the following contents:
} __McDonalds__
}
} ...
} ...
} ...(stuff deleted)
}
} __Happy_Meal__
}
} With sed I would do something like
}
} sed -n "/__McDonalds__/,/__Happy_Meal__/p" Menu } } I can not find
anything comparable in Ruby. I may be using the wrong } words when I
searched google for ruby line address.
} Any help will be appreciated.

Well, sometimes sed (or awk, which does the same thing even more simply:
awk '/__McDonalds__/,/__Happy_Meal__/') is the right tool. If you are
selected this subset of lines for further processing in ruby, however
try
this:

inrange = false
lines = open(file).read.split("\n").select { |line|
  inrange &&= not /__Happy_Meal__/ === line
  inrange ||= /__McDonalds__/ === line
}

} Thank you,
} Raymond
--Greg

Gregory Seidman wrote:

inrange = false
lines = open(file).read.split("\n").select { |line|
  inrange &&= not /__Happy_Meal__/ === line
  inrange ||= /__McDonalds__/ === line
}

There is a lesser-known (and usually frowned upon?) feature in Ruby that treats Range notation differently in a "boolean context."

IO.foreach(file) do |line| # use this rather that loading the whole file
   if line =~ /__McDonalds__/ .. line =~ /__Happy_Meal__/
     do_stuff_with line
   end
end

Devin

Devin Mullins wrote:

Gregory Seidman wrote:

inrange = false
lines = open(file).read.split("\n").select { |line|
  inrange &&= not /__Happy_Meal__/ === line
  inrange ||= /__McDonalds__/ === line
}

There is a lesser-known (and usually frowned upon?) feature in Ruby that
treats Range notation differently in a "boolean context."

IO.foreach(file) do |line| # use this rather that loading the whole file
  if line =~ /__McDonalds__/ .. line =~ /__Happy_Meal__/
    do_stuff_with line
  end
end

So -this- is what that does?

Does this do that?

Does anyone know what that notation does?

David Vallner
Incoherent

There is a lesser-known (and usually frowned upon?) feature in Ruby that
treats Range notation differently in a "boolean context."

IO.foreach(file) do |line| # use this rather that loading the whole file
  if line =~ /__McDonalds__/ .. line =~ /__Happy_Meal__/
    do_stuff_with line
  end
end

So -this- is what that does?

Does this do that?

yes.

Does anyone know what that notation does?

it's a boolean toggle.

well doccumented in pickaxe and every perl book out there - if not somewhat
esoteric.

cheers.

-a

···

On Wed, 6 Dec 2006, David Vallner wrote:
--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama