[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

if / else, how to include next line

Marc Hoeppner

7/11/2007 8:36:00 AM


Hi everyone,

absolute beginner here, so bare with me ;)

The following issue came up and I can't figure out how to solve.
Probably nothing very complicated, tho.

I want to load a text file via ARGV[0] and then search it for a key
word. If this key word is found, it should be printed (puts) and...and
this is very I am stuck ...it should also included the next 8 lines. The
file structure looks like this:

KOG0003
Sc 000000000
Dr 000000000
Ar 001010011
Ca 000100100
Ho 001010010
Sa 010000000
An 100000100
Pl 000001000
KOG0009
Sc 000100
Dr 100000
Ar 001001
Ca 101000
Ho 101010
Sa 010000
An 100000
Pl 001000

So lets say I want to select for a specific KOG (or a list of KOGs) and
write them together with the associated lines into a new file. I guess
the issue at the moment is, that when I open the ARGV[0], it reads one
line at a time - cant quite figure out how to include the "go to next
line and puts it, too" part.

Any help pointing me in the right direction would be greatly appreciated

/Marc

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

12 Answers

Robert Dober

7/11/2007 8:52:00 AM

0

On 7/11/07, Marc Hoeppner <marc.hoeppner@molbio.su.se> wrote:
>
> Hi everyone,
>
> absolute beginner here, so bare with me ;)
>
> The following issue came up and I can't figure out how to solve.
> Probably nothing very complicated, tho.
>
> I want to load a text file via ARGV[0] and then search it for a key
> word. If this key word is found, it should be printed (puts) and...and
> this is very I am stuck ...it should also included the next 8 lines. The
> file structure looks like this:
>
> KOG0003
> Sc 000000000
> Dr 000000000
> Ar 001010011
> Ca 000100100
> Ho 001010010
> Sa 010000000
> An 100000100
> Pl 000001000
> KOG0009
> Sc 000100
> Dr 100000
> Ar 001001
> Ca 101000
> Ho 101010
> Sa 010000
> An 100000
> Pl 001000
>
> So lets say I want to select for a specific KOG (or a list of KOGs) and
> write them together with the associated lines into a new file. I guess
> the issue at the moment is, that when I open the ARGV[0], it reads one
> line at a time - cant quite figure out how to include the "go to next
> line and puts it, too" part.
>
> Any help pointing me in the right direction would be greatly appreciated
>
> /Marc
>
> --
> Posted via http://www.ruby-....
>
You can read all files indicated by args or stdin with ARGF
ARGF.readlines will slurp in the whole file, but if it is large that
might be a problem.

Let us try a robust solution first

count = 0
ARGF.each do |line| ## treating a line at turn
puts line unless count.zero?
count = [0, count-1].max
if line =~ /your keyword or something/ then
puts line
count = 8
end
end

Now that is one ruby solution, maybe you want to use grep, sorry if
this is noise but maybe this helps too.
grep -A8 youre_keywoarde_blease ...

HTH
Robert


>


--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Stefano Crocco

7/11/2007 8:54:00 AM

0

Alle mercoledì 11 luglio 2007, Marc Hoeppner ha scritto:
> Hi everyone,
>
> absolute beginner here, so bare with me ;)
>
> The following issue came up and I can't figure out how to solve.
> Probably nothing very complicated, tho.
>
> I want to load a text file via ARGV[0] and then search it for a key
> word. If this key word is found, it should be printed (puts) and...and
> this is very I am stuck ...it should also included the next 8 lines. The
> file structure looks like this:
>
> KOG0003
> Sc 000000000
> Dr 000000000
> Ar 001010011
> Ca 000100100
> Ho 001010010
> Sa 010000000
> An 100000100
> Pl 000001000
> KOG0009
> Sc 000100
> Dr 100000
> Ar 001001
> Ca 101000
> Ho 101010
> Sa 010000
> An 100000
> Pl 001000
>
> So lets say I want to select for a specific KOG (or a list of KOGs) and
> write them together with the associated lines into a new file. I guess
> the issue at the moment is, that when I open the ARGV[0], it reads one
> line at a time - cant quite figure out how to include the "go to next
> line and puts it, too" part.
>
> Any help pointing me in the right direction would be greatly appreciated
>
> /Marc

You can try this:

require 'enumerator'
text.each_slice(9) do |a|
puts a.join "\n" if a.first == key
end

This will pass the array the lines grouped in arrays of 9 lines each (i.e, in
the first iteration the array will contain the lines from KOG0003 to Pl
000001000, the second time from KOG0009 to Pl 001000, and so on). The line
with the key word will be the first of each array, so you print the array
only if it is equal to the key you chose.

I hope this helps

Stefano

John Joyce

7/11/2007 9:00:00 AM

0


On Jul 11, 2007, at 3:35 AM, Marc Hoeppner wrote:

>
> Hi everyone,
>
> absolute beginner here, so bare with me ;)
>
> The following issue came up and I can't figure out how to solve.
> Probably nothing very complicated, tho.
>
> I want to load a text file via ARGV[0] and then search it for a key
> word. If this key word is found, it should be printed (puts) and...and
> this is very I am stuck ...it should also included the next 8
> lines. The
> file structure looks like this:
>
> KOG0003
> Sc 000000000
> Dr 000000000
> Ar 001010011
> Ca 000100100
> Ho 001010010
> Sa 010000000
> An 100000100
> Pl 000001000
> KOG0009
> Sc 000100
> Dr 100000
> Ar 001001
> Ca 101000
> Ho 101010
> Sa 010000
> An 100000
> Pl 001000
>
> So lets say I want to select for a specific KOG (or a list of KOGs)
> and
> write them together with the associated lines into a new file. I guess
> the issue at the moment is, that when I open the ARGV[0], it reads one
> line at a time - cant quite figure out how to include the "go to next
> line and puts it, too" part.
>
> Any help pointing me in the right direction would be greatly
> appreciated
>
> /Marc
>
> --
> Posted via http://www.ruby-....
>

You can use a heredoc to maintain all the whitespace.
Here's some info:
http://blog.jayfields.com/2006/12/ruby-multiline-strings...
or.html
Then just assign the heredoc to a variable
last_8_lines = <<-heredoc_ender
KOG0003
Sc 000000000
Dr 000000000
Ar 001010011
Ca 000100100
Ho 001010010
Sa 010000000
An 100000100
Pl 000001000
KOG0009
Sc 000100
Dr 100000
Ar 001001
Ca 101000
Ho 101010
Sa 010000
An 100000
Pl 001000
heredoc_ender

When you want to use it, just :
puts last_8_lines

You can also use string interpolation with heredocs


#{keyword_string}

John Joyce

John Joyce

7/11/2007 9:18:00 AM

0


On Jul 11, 2007, at 4:00 AM, John Joyce wrote:

>
> On Jul 11, 2007, at 3:35 AM, Marc Hoeppner wrote:
>
>>
>> Hi everyone,
>>
>> absolute beginner here, so bare with me ;)
>>
>> The following issue came up and I can't figure out how to solve.
>> Probably nothing very complicated, tho.
>>
>> I want to load a text file via ARGV[0] and then search it for a key
>> word. If this key word is found, it should be printed (puts)
>> and...and
>> this is very I am stuck ...it should also included the next 8
>> lines. The
>> file structure looks like this:
>>
>> KOG0003
>> Sc 000000000
>> Dr 000000000
>> Ar 001010011
>> Ca 000100100
>> Ho 001010010
>> Sa 010000000
>> An 100000100
>> Pl 000001000
>> KOG0009
>> Sc 000100
>> Dr 100000
>> Ar 001001
>> Ca 101000
>> Ho 101010
>> Sa 010000
>> An 100000
>> Pl 001000
>>
>> So lets say I want to select for a specific KOG (or a list of
>> KOGs) and
>> write them together with the associated lines into a new file. I
>> guess
>> the issue at the moment is, that when I open the ARGV[0], it reads
>> one
>> line at a time - cant quite figure out how to include the "go to next
>> line and puts it, too" part.
>>
>> Any help pointing me in the right direction would be greatly
>> appreciated
>>
>> /Marc
>>
>> --
>> Posted via http://www.ruby-....
>>
>
> You can use a heredoc to maintain all the whitespace.
> Here's some info:
> http://blog.jayfields.com/2006/12/ruby-multiline-strings...
> or.html
> Then just assign the heredoc to a variable
> last_8_lines = <<-heredoc_ender
> KOG0003
> Sc 000000000
> Dr 000000000
> Ar 001010011
> Ca 000100100
> Ho 001010010
> Sa 010000000
> An 100000100
> Pl 000001000
> KOG0009
> Sc 000100
> Dr 100000
> Ar 001001
> Ca 101000
> Ho 101010
> Sa 010000
> An 100000
> Pl 001000
> heredoc_ender
>
> When you want to use it, just :
> puts last_8_lines
>
> You can also use string interpolation with heredocs
>
>
> #{keyword_string}
>
> John Joyce
>
Oops, I misunderstood the OP!
You might also use ri to look up "readlines"
your loop mechanism could be done many ways.
but Robert gave one way.
Definitely read one line at a time, searching for the string.
if found, start counting.

8 lines

assign the search line to a variable, keep reusing that variable
until you get a match,
after the match, the next 8 lines are each just concatenated onto the
end of the variable.

Marc Hoeppner

7/11/2007 9:24:00 AM

0

Thanks a lot, works now!

/Marc

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

Robert Dober

7/11/2007 9:27:00 AM

0

On 7/11/07, Stefano Crocco <stefano.crocco@alice.it> wrote:
> Alle mercoledì 11 luglio 2007, Marc Hoeppner ha scritto:
> > Hi everyone,
> >
> > absolute beginner here, so bare with me ;)
> >
> > The following issue came up and I can't figure out how to solve.
> > Probably nothing very complicated, tho.
> >
> > I want to load a text file via ARGV[0] and then search it for a key
> > word. If this key word is found, it should be printed (puts) and...and
> > this is very I am stuck ...it should also included the next 8 lines. The
> > file structure looks like this:
> >
> > KOG0003
> > Sc 000000000
> > Dr 000000000
> > Ar 001010011
> > Ca 000100100
> > Ho 001010010
> > Sa 010000000
> > An 100000100
> > Pl 000001000
> > KOG0009
> > Sc 000100
> > Dr 100000
> > Ar 001001
> > Ca 101000
> > Ho 101010
> > Sa 010000
> > An 100000
> > Pl 001000
> >
> > So lets say I want to select for a specific KOG (or a list of KOGs) and
> > write them together with the associated lines into a new file. I guess
> > the issue at the moment is, that when I open the ARGV[0], it reads one
> > line at a time - cant quite figure out how to include the "go to next
> > line and puts it, too" part.
> >
> > Any help pointing me in the right direction would be greatly appreciated
> >
> > /Marc
>
> You can try this:
>
> require 'enumerator'
> text.each_slice(9) do |a|
> puts a.join "\n" if a.first == key
> end

That is nice code, I did not want to rely on the exact format of the
input as I learned to distrust specifications ;). But you do what OP
asked for.
Allow me to recall a small hint David Black has given some time ago

puts a
is equivalent to
puts a.join("\n")
>
> This will pass the array the lines grouped in arrays of 9 lines each (i.e, in
> the first iteration the array will contain the lines from KOG0003 to Pl
> 000001000, the second time from KOG0009 to Pl 001000, and so on). The line
> with the key word will be the first of each array, so you print the array
> only if it is equal to the key you chose.
>
> I hope this helps
>
> Stefano
>
>
Cheers
Robert

--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Stefano Crocco

7/11/2007 9:41:00 AM

0

Alle mercoledì 11 luglio 2007, Robert Dober ha scritto:
> Allow me to recall a small hint David Black has given some time ago
>
> puts a
> is equivalent to
> puts a.join("\n")

You're right. I didn't think to try it.

Stefano

Marc Hoeppner

7/11/2007 10:22:00 AM

0


>
> count = 0
> ARGF.each do |line| ## treating a line at turn
> puts line unless count.zero?
> count = [0, count-1].max
> if line =~ /your keyword or something/ then
> puts line
> count = 8
> end
> end
>

Ok, I started with this one, but run into one problem - again probably
simple...
The way this is written it asks for a regexp as a keyword. Now, I do
have a text file, in which I have a number of key words, one in each
line. What I wasnt able to figure out thus far was how to change the
above code so that it would expect a variable instead of a regexp.

When I defined a variable within the code var1 = 'KOG0019' and tried to
use it as an argument ala if = var1 then it did something..., but
instead of finding the corresponding line and copying the following at
lines it copies like 12000 lines and puts the keyword in every second
line...

/Marc

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

Robert Dober

7/11/2007 11:13:00 AM

0

On 7/11/07, Marc Hoeppner <marc.hoeppner@molbio.su.se> wrote:
>
> >
> > count = 0
> > ARGF.each do |line| ## treating a line at turn
> > puts line unless count.zero?
> > count = [0, count-1].max
> > if line =~ /your keyword or something/ then
> > puts line
> > count = 8
> > end
> > end
> >
>
> Ok, I started with this one, but run into one problem - again probably
> simple...
> The way this is written it asks for a regexp as a keyword. Now, I do
> have a text file, in which I have a number of key words, one in each
> line. What I wasnt able to figure out thus far was how to change the
> above code so that it would expect a variable instead of a regexp.
>
> When I defined a variable within the code var1 = 'KOG0019' and tried to

I had no idea what you wanted exactly, here are some possibilites
(a) always the same string
if line == "KOG0019"
(b) containing the same string
if line =~ /KOG0019/
or my favorite idiom
if /KOG0019/ === line
(c) KOG followed by digits something
if /KOG\d+/ === line
(d) KOG and exactly 4 digits
if /KOG\d{4}/ === line
(e) KOG and some digits with no more text thereafter
if /KOG\d+\s*$/ === line

This should get you going;) if not try to learn more about Regexps; by
scanning this list or reading the perl man page about regexps (the
baisc stuff is the same and gets you a long way already). The ultimate
guide seems to be Friedl's "Mastering Regular Expressions".

Cheers
Robert

> use it as an argument ala if = var1 then it did something..., but
> instead of finding the corresponding line and copying the following at
> lines it copies like 12000 lines and puts the keyword in every second
> line...
>
> /Marc
>
> --
> Posted via http://www.ruby-....
>
>


--
I always knew that one day Smalltalk would replace Java.
I just didn't know it would be called Ruby
-- Kent Beck

Marc Hoeppner

7/11/2007 11:28:00 AM

0

Hm, maybe I was in fact a bit vague here, sorry.

I think grep will do the job (sometimes its just simpler than one
expected...), but now just out of curiosity:

I have one file, structured as shown above. It contains some 600
"entries" (that is a KOG-number followed by 8 lines of information). Out
of these 600-someting entries, I only need a particular subset. The
information on which KOG-entries I need are in a second text file
(basically the KOG-numbers, one in each line), like so:

KOG0019
KOG0101
KOG0245
etc

Ideally,the program would read this keyword-file, store the information
in a variable (an array, I guess) and then use this array to identify
the entries in the "main" file and puts them into stdout.

*scratches head*


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