Help: Efficient regular expression

It's not fancy, but I'll throw it in:

s = 'root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bash -x -s'
_, pid, _, cmd = *(s.match /(\d+)\s.*(:\d+){2}\s(.*?)$/)

so, if you're using a hash like I think you might be:

s = <output of ps command>
h = {}
s.each_line do |line|
  _, pid, _, cmd = *(line.match /(\d+)\s.*(:\d+){2}\s(.*?)$/)
  h[pid] = cmd
end

I think that should work.

Todd

_, pid

···

On 7/10/07, Divya Badrinath <dbadrinath@dash.net> wrote:

Robert Dober wrote:
> On 7/10/07, James Edward Gray II <james@grayproductions.net> wrote:
>> sec, last = cols.values_at(1, -1)
> Very interesting James, I seem to be rather extreme and
>
> sec, last = string.split.values_at(1, -1)
> might be a tad to long for one line in your style, however Ruby syntax
> just supports this marvelous syntax :slight_smile:
>
> sec, last = string.split.
> values_at(1, -1)
>
> Robert

cmd = string[/\s(\S+)$/, 1]
doesnt fetch me anything:)

program=string.split.last
what if
string = "root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bash -x
-s"
it fetches only -s for me.
sec, last = string.split.values_at(1, -1)
doesnt work for the same reason
i need everything after 00.00.00 till the end
i.e., /bin/bash -x -s

program=string[/[a-z\/]+$/]
the command column mauy start with character. i dont want to limit it in
my regexp. it has to be generic.

with all your comments, i tried
      pid = run_process[/\s(\d+)/, 1]
      cmd = run_process[/:\d+:\d+\s(\S.*)\s$/, 1]

is there any other way?

Just limit the split and you should go with command arguments...

On Behalf Of Divya Badrinath:
# string = "root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bash -x -s"
# it fetches only -s for me.
# sec, last = string.split.values_at(1, -1)
# doesnt work for the same reason
# i need everything after 00.00.00 till the end
# i.e., /bin/bash -x -s

you can modify the non-regex solutions since they are just plain array manipulations

irb(main):003:0> str = "root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bas
h -x -s"
=> "root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bash -x -s"
irb(main):006:0> astr = str.split
=> ["root", "14051", "14033", "3", "08:39", "pts/2", "00:00:00", "/bin/bash", "-
x", "-s"]
irb(main):007:0> pid = astr[1]
=> "14051"
irb(main):010:0> cmd = astr[7..-1].join " "
=> "/bin/bash -x -s"

or

irb(main):024:0> pid,*cmd = astr.values_at(1,7..-1)
=> ["14051", "/bin/bash", "-x", "-s"]
irb(main):025:0> pid
=> "14051"
irb(main):026:0> cmd
=> ["/bin/bash", "-x", "-s"]
irb(main):027:0> cmd = cmd.join " "
=> "/bin/bash -x -s"

<snip>

cmd = string[/\s(\S+)$/, 1]
doesnt fetch me anything:)

No idea that was not my code :slight_smile:

program=string.split.last
what if
string = "root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bash -x
-s"
it fetches only -s for me.

As simple as possible, but not simpler. Now we are in the simpler case :slight_smile:
But see below

program=string[/[a-z\/]+$/]
the command column mauy start with character. i dont want to limit it in
my regexp. it has to be generic.

with all your comments, i tried
      pid = run_process[/\s(\d+)/, 1]
      cmd = run_process[/:\d+:\d+\s(\S.*)\s$/, 1]

Does not work the :\d+ stuff might be a parameter of the program :frowning:

is there any other way?

Yep :slight_smile: counting fields after all
   x = split
   y= x[1]
   z = x[7..-1].join(" ")

There might still be a pitfall though in case of some old processes
where you will have to analyse if the date takes one or two fields if
memory serves.

HTH
Robert

···

On 7/10/07, Divya Badrinath <dbadrinath@dash.net> wrote:

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

> >

<snip>

> Very interesting James, I seem to be rather extreme and
>
> sec, last = string.split.values_at(1, -1)
> might be a tad to long for one line in your style, however Ruby syntax
> just supports this marvelous syntax :slight_smile:
>
> sec, last = string.split.
> values_at(1, -1)

What is your terminal width, 30?

oops wrong thread, I was caught in the "Beautiful Code Thread".

Sorry
Robert

···

On 7/10/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:

On 7/10/07, Robert Dober <robert.dober@gmail.com> wrote:
> On 7/10/07, James Edward Gray II <james@grayproductions.net> wrote:
> > On Jul 10, 2007, at 3:25 PM, Divya Badrinath wrote:

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

...unless the process start time is one of the output columns and it goes from 'HH:MM' to 'Mon dd' for a process that runs long enough.

If you really can't change the ps options, suck it up, count columns, forget the regexp, and be done.

-Rob

Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

···

On Jul 10, 2007, at 7:54 PM, Florian Aßmann wrote:

Just limit the split and you should go with command arguments...

# On Behalf Of Divya Badrinath:
# # string = "root 14051 14033 3 08:39 pts/2 00:00:00
# /bin/bash -x -s"
# # it fetches only -s for me.
# # sec, last = string.split.values_at(1, -1)
# # doesnt work for the same reason
# # i need everything after 00.00.00 till the end
# # i.e., /bin/bash -x -s

···

From: Peña, Botp [mailto:botp@delmonte-phil.com]
#
# you can modify the non-regex solutions since they are just
# plain array manipulations
#
# irb(main):003:0> str = "root 14051 14033 3 08:39 pts/2
# 00:00:00 /bin/bas
# h -x -s"
# => "root 14051 14033 3 08:39 pts/2 00:00:00 /bin/bash -x -s"
# irb(main):006:0> astr = str.split
# => ["root", "14051", "14033", "3", "08:39", "pts/2",
# "00:00:00", "/bin/bash", "-
# x", "-s"]
# irb(main):007:0> pid = astr[1]
# => "14051"
# irb(main):010:0> cmd = astr[7..-1].join " "
# => "/bin/bash -x -s"
#
# or
#
# irb(main):024:0> pid,*cmd = astr.values_at(1,7..-1)
# => ["14051", "/bin/bash", "-x", "-s"]
# irb(main):025:0> pid
# => "14051"
# irb(main):026:0> cmd
# => ["/bin/bash", "-x", "-s"]
# irb(main):027:0> cmd = cmd.join " "
# => "/bin/bash -x -s"

i forgot to add the last one; it's niftier, so i would not want you to miss it.

irb(main):060:0> pid,cmd=str.split(" ",8).values_at(1,7)
=> ["14051", "/bin/bash -x -s"]
irb(main):061:0> pid
=> "14051"
irb(main):062:0> cmd
=> "/bin/bash -x -s"

i totally forgot about the second param of split. ruby is cool, indeed :slight_smile:
kind regards -botp