[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Help on best way to gather/sort results [Array/Hash]?

Tony De

3/29/2008 5:03:00 AM

Greetings ruby fans,

I'm a greenhorn at this cool lang ruby. Much to learn. Perhaps you
chaps could help me with an issue I have. I've read through a number of
the post on sorting Arrays and Hashes. And yet I can't seem to put my
finger on the solution. I want to sort on the second column. So it
seemed from what information I gathered, that I need to gather my
results into a hash. Am I on the right track? Oh, let me tell you what
your looking at here; I am scanning each mail file in our queue for
commonalites (spammer) instead of the useless (my opinoin) qmHandle we
have for qmail. So, I've got a working prototype. If you could help me
on my sort and if you have any other comments/suggestions to throw my
way I'm sure I could learn a thing or two. Being new to ruby, there's a
lot of new ideas here. Thank guys.

Code:
#!/usr/local/bin/ruby -w
require 'find'

@results = Array.new

# Iterate through the child directories & call the parse file method
def scan_dirs
root = "/var/qmail/queue/mess"
Find.find(root) do |file|
parse_file(file)
end
@results.sort!
print_results
end

# Parse each file for the information we want
def parse_file(path)
file = path[(path.length-7), path.length]
sourceip = ""
email = ""
subject = ""
email_found = false
line_no = 0

File.open(path, 'r').each do |line|

line = line.strip # Remove any \n\r nil, etc
line_no += 1

if line_no == 1
if line.match("invoked for bounce")
# Internal Bounce Msg
sourceip = "SMTP"
end
end

if (line_no == 2 and sourceip.empty?)
if line.match("webmail.commspeed.net")
sourceip = "Webmail"
else
sourceip = line.scan(/\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\b/)
if sourceip.empty?
sourceip = "No Source IP**"
end
end
end

if (line.match("SquirrelMail") and sourceip == "Webmail") or
(line.match("From:") and sourceip != "Webmail")
if email.empty?
email = get_email(line)
end
end

if line.match("Subject:") and subject.empty?
subject = truncate(line,50)
end

if line_no == 20 #Nothing more we want to read in the file
@results << ["#{file}", "#{sourceip}", "#{email}", "#{subject}"]
line_no = 0
return
end
end
end

# Truncate subject line
def truncate(string, width)
if string.length <= width
string
else
string[0, width-3] + "..."
end
end

# Print out results
def print_results
print "\e[2J\e[f"

print "Mess#".ljust(10," ")
print "Source".ljust(18," ")
print "Email Addrress".ljust(30, " ")
print "Subject".ljust(50, " ")
1.times { print "\n" }
111.times { print "-" }
1.times { print "\n" }

@results.each do |line|
print line[0].ljust(10," ")
print line[1].ljust(18," ")
print line[2].ljust(30, " ")
print line[3].ljust(50, " ")

1.times { print "\n" }
end
end

# Get email address from line/string
def get_email(line_to_parse)
# Pull the email address from the line
line_to_parse.scan(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i).flatten
end

# Ok, begin our scan
scan_dirs
exit

Partial results listing: (I've modified the content to protect privacy)
Mess# Source Email Addrress Subject
---------------------------------------------------------------------------------------------------------------
3360108 111.111.17.1 hobby@emailhost.net
3360167 111.111.7.213 hunter@emailhost.ner Subject:
Removed to protect the innocent....
3360186 Webmail fisher@emailhost.net Subject:
Removed to protect the innocent
3360209 111.111.40.10 curator@aneatmuseum.org
3360215 111.111.15.110 blueprints@emailhost.net Subject:
Removed to protect the innocent
3360217 111.111.9.248 user1@emailhost.net Subject:
Removed to protect the innocent
3360226 111.111.11.43 user@emailhost.net Subject:
Removed to protect the innocent
3360228 111.111.16.34 user@emailhost.net Subject:
Pictures
3360241 111.111.18.73 joe@agooduser.com Subject:
Removed to protect the innocent
3360242 111.111.14.109 user@emailhost.net Subject:
Emailing: maps.htm
--
Posted via http://www.ruby-....

17 Answers

Todd Benson

3/29/2008 5:33:00 AM

0

On Sat, Mar 29, 2008 at 12:02 AM, Tony De <tonydema@gmail.com> wrote:
> Greetings ruby fans,
>
> I'm a greenhorn at this cool lang ruby. Much to learn. Perhaps you
> chaps could help me with an issue I have. I've read through a number of
> the post on sorting Arrays and Hashes. And yet I can't seem to put my
> finger on the solution. I want to sort on the second column. So it
> seemed from what information I gathered, that I need to gather my
> results into a hash. Am I on the right track? Oh, let me tell you what
> your looking at here; I am scanning each mail file in our queue for
> commonalites (spammer) instead of the useless (my opinoin) qmHandle we
> have for qmail. So, I've got a working prototype. If you could help me
> on my sort and if you have any other comments/suggestions to throw my
> way I'm sure I could learn a thing or two. Being new to ruby, there's a
> lot of new ideas here. Thank guys.
>

Being a little lazy at the moment to go through the code, have you
looked at #sort_by{}?

Todd

Tony De

3/29/2008 5:41:00 AM

0

Todd Benson wrote:
> On Sat, Mar 29, 2008 at 12:02 AM, Tony De <tonydema@gmail.com> wrote:
>> have for qmail. So, I've got a working prototype. If you could help me
>> on my sort and if you have any other comments/suggestions to throw my
>> way I'm sure I could learn a thing or two. Being new to ruby, there's a
>> lot of new ideas here. Thank guys.
>>
>
> Being a little lazy at the moment to go through the code, have you
> looked at #sort_by{}?
>
> Todd

I believe I ran across it but I recall it blew up when I worked with it.
Likely an issue with my as the unskilled ruby coder than the method
itself. I'll take another look. Thanks

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

Tony De

3/29/2008 5:50:00 AM

0

Tony De wrote:
> Todd Benson wrote:
>> On Sat, Mar 29, 2008 at 12:02 AM, Tony De <tonydema@gmail.com> wrote:
>>> have for qmail. So, I've got a working prototype. If you could help me
>>> on my sort and if you have any other comments/suggestions to throw my
>>> way I'm sure I could learn a thing or two. Being new to ruby, there's a
>>> lot of new ideas here. Thank guys.
>>>
>>
>> Being a little lazy at the moment to go through the code, have you
>> looked at #sort_by{}?
>>
>> Todd
>
> I believe I ran across it but I recall it blew up when I worked with it.
> Likely an issue with my as the unskilled ruby coder than the method
> itself. I'll take another look. Thanks
>
> tonyd

Ok, tried this @results.sort_by { |a| a[1] } - thinking that I want to
sort on the second element in my array "Source". No sort was performed
at all. Scratching my head..

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

Christian

3/29/2008 6:04:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Wouldn't you want something like @results.sort {|x, y| y[1] <=> x[1]}?

On Sat, Mar 29, 2008 at 3:49 PM, Tony De <tonydema@gmail.com> wrote:

> Tony De wrote:
> > Todd Benson wrote:
> >> On Sat, Mar 29, 2008 at 12:02 AM, Tony De <tonydema@gmail.com> wrote:
> >>> have for qmail. So, I've got a working prototype. If you could help
> me
> >>> on my sort and if you have any other comments/suggestions to throw my
> >>> way I'm sure I could learn a thing or two. Being new to ruby,
> there's a
> >>> lot of new ideas here. Thank guys.
> >>>
> >>
> >> Being a little lazy at the moment to go through the code, have you
> >> looked at #sort_by{}?
> >>
> >> Todd
> >
> > I believe I ran across it but I recall it blew up when I worked with it.
> > Likely an issue with my as the unskilled ruby coder than the method
> > itself. I'll take another look. Thanks
> >
> > tonyd
>
> Ok, tried this @results.sort_by { |a| a[1] } - thinking that I want to
> sort on the second element in my array "Source". No sort was performed
> at all. Scratching my head..
>
> tonyd
> --
> Posted via http://www.ruby-....
>
>


--

"Every child has many wishes. Some include a wallet, two chicks and a cigar,
but that's another story."

Christian

3/29/2008 6:06:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Or perhaps what you're really wanting, is something like
@results.sort_by{|a| @results[1]}?

On Sat, Mar 29, 2008 at 4:03 PM, Christian <chippersbox@gmail.com> wrote:

> Wouldn't you want something like @results.sort {|x, y| y[1] <=> x[1]}?
>
>
> On Sat, Mar 29, 2008 at 3:49 PM, Tony De <tonydema@gmail.com> wrote:
>
> > Tony De wrote:
> > > Todd Benson wrote:
> > >> On Sat, Mar 29, 2008 at 12:02 AM, Tony De <tonydema@gmail.com> wrote:
> > >>> have for qmail. So, I've got a working prototype. If you could
> > help me
> > >>> on my sort and if you have any other comments/suggestions to throw
> > my
> > >>> way I'm sure I could learn a thing or two. Being new to ruby,
> > there's a
> > >>> lot of new ideas here. Thank guys.
> > >>>
> > >>
> > >> Being a little lazy at the moment to go through the code, have you
> > >> looked at #sort_by{}?
> > >>
> > >> Todd
> > >
> > > I believe I ran across it but I recall it blew up when I worked with
> > it.
> > > Likely an issue with my as the unskilled ruby coder than the method
> > > itself. I'll take another look. Thanks
> > >
> > > tonyd
> >
> > Ok, tried this @results.sort_by { |a| a[1] } - thinking that I want to
> > sort on the second element in my array "Source". No sort was performed
> > at all. Scratching my head..
> >
> > tonyd
> > --
> > Posted via http://www.ruby-....
> >
> >
>
>
> --
>
> "Every child has many wishes. Some include a wallet, two chicks and a
> cigar, but that's another story."
>



--

"Every child has many wishes. Some include a wallet, two chicks and a cigar,
but that's another story."

Tony De

3/29/2008 6:14:00 AM

0

Christian wrote:
> Wouldn't you want something like @results.sort {|x, y| y[1] <=> x[1]}?
>
> On Sat, Mar 29, 2008 at 3:49 PM, Tony De <tonydema@gmail.com> wrote:
>
>> >>
>>
>> Ok, tried this @results.sort_by { |a| a[1] } - thinking that I want to
>> sort on the second element in my array "Source". No sort was performed
>> at all. Scratching my head..
>>
>> tonyd
>> --
>> Posted via http://www.ruby-....
>>
>>
>
>
> --
>
> "Every child has many wishes. Some include a wallet, two chicks and a
> cigar,
> but that's another story."


Just tried that. No sort. Just for ref. My array struct looks like
this:
@results << ["#{file}", "#{sourceip}", "#{email}", "#{subject}"]

I want to sort on sourceip. Thanks guys.


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

Christian

3/29/2008 6:19:00 AM

0

[Note: parts of this message were removed to make it a legal post.]

Does the sort work if you just put in the sourceip? Say, you did @results <<
"#{sourceip}", and then used @results.sort. Does it still not sort?

On Sat, Mar 29, 2008 at 4:14 PM, Tony De <tonydema@gmail.com> wrote:

> Christian wrote:
> > Wouldn't you want something like @results.sort {|x, y| y[1] <=> x[1]}?
> >
> > On Sat, Mar 29, 2008 at 3:49 PM, Tony De <tonydema@gmail.com> wrote:
> >
> >> >>
> >>
> >> Ok, tried this @results.sort_by { |a| a[1] } - thinking that I want to
> >> sort on the second element in my array "Source". No sort was performed
> >> at all. Scratching my head..
> >>
> >> tonyd
> >> --
> >> Posted via http://www.ruby-....
> >>
> >>
> >
> >
> > --
> >
> > "Every child has many wishes. Some include a wallet, two chicks and a
> > cigar,
> > but that's another story."
>
>
> Just tried that. No sort. Just for ref. My array struct looks like
> this:
> @results << ["#{file}", "#{sourceip}", "#{email}", "#{subject}"]
>
> I want to sort on sourceip. Thanks guys.
>
>
> --
> Posted via http://www.ruby-....
>
>


--

"Every child has many wishes. Some include a wallet, two chicks and a cigar,
but that's another story."

Christopher Dicely

3/29/2008 6:29:00 AM

0

On Fri, Mar 28, 2008 at 10:49 PM, Tony De <tonydema@gmail.com> wrote:
>
> Tony De wrote:
> > Todd Benson wrote:
> >> On Sat, Mar 29, 2008 at 12:02 AM, Tony De <tonydema@gmail.com> wrote:
> >>> have for qmail. So, I've got a working prototype. If you could help me
> >>> on my sort and if you have any other comments/suggestions to throw my
> >>> way I'm sure I could learn a thing or two. Being new to ruby, there's a
> >>> lot of new ideas here. Thank guys.
> >>>
> >>
> >> Being a little lazy at the moment to go through the code, have you
> >> looked at #sort_by{}?
> >>
> >> Todd
> >
> > I believe I ran across it but I recall it blew up when I worked with it.
> > Likely an issue with my as the unskilled ruby coder than the method
> > itself. I'll take another look. Thanks
> >
> > tonyd
>
> Ok, tried this @results.sort_by { |a| a[1] } - thinking that I want to
> sort on the second element in my array "Source". No sort was performed
> at all. Scratching my head..

Did you capture the result? #sort and #sort_by are non-destructive, so this:

---
a= [ [0,3], [4,1], [5,2]]
a.sort_by {|i| i[1]}
puts a.inspect
---
gives: "[[0,3],[4,1],[5,2]]"

but this:
---
a= [ [0,3], [4,1], [5,2]]
b=a.sort_by {|i| i[1]}
puts b.inspect
---
gives: "[[4,1],[5,2],[0,3]]"

There is a destructive version of #sort (#sort!), but not of #sort_by.

Tony De

3/29/2008 6:32:00 AM

0

Christian wrote:
> Does the sort work if you just put in the sourceip? Say, you did
> @results <<
> "#{sourceip}", and then used @results.sort. Does it still not sort?
>
> On Sat, Mar 29, 2008 at 4:14 PM, Tony De <tonydema@gmail.com> wrote:
>
>> >>
>> > cigar,
>> --
>> Posted via http://www.ruby-....
>>
>>
>
>
> --
>
> "Every child has many wishes. Some include a wallet, two chicks and a
> cigar,
> but that's another story."

Yeah, if I only collect the "sourceip" and do a @results.sort it doesn't
work. I have to do a .sort!. And the same behaviour with @results <<
["#{file}", "#{sourceip}", "#{email}", "#{subject}"]. @results.sort
does not sort. @results.sort! does. And I tried sort! as an after
thought.

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

Tony De

3/29/2008 6:35:00 AM

0

Tony De wrote:
> Christian wrote:
>> Does the sort work if you just put in the sourceip? Say, you did
>> @results <<
>> "#{sourceip}", and then used @results.sort. Does it still not sort?
>>
>> On Sat, Mar 29, 2008 at 4:14 PM, Tony De <tonydema@gmail.com> wrote:
>>
>>> >>
>>> > cigar,
>>> --
>>> Posted via http://www.ruby-....
>>>
>>>
>>
>>
>> --
>>
>> "Every child has many wishes. Some include a wallet, two chicks and a
>> cigar,
>> but that's another story."
>
> Yeah, if I only collect the "sourceip" and do a @results.sort it doesn't
> work. I have to do a .sort!. And the same behaviour with @results <<
> ["#{file}", "#{sourceip}", "#{email}", "#{subject}"]. @results.sort
> does not sort. @results.sort! does. And I tried sort! as an after
> thought.
>
> tonyd

"as an after thought" got me to thinking. Try @results.sort! {|x, y|
y[1] <=> x[1]}. And it works. .sort fails, .sort! works. Any ideas
why? I would really like to understand this a little more. Thanks
guys, all of you, for your help.

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