regex matching - multiple lines

I've been scratching my head a bit on this one (regex isn't my strong suit).  I am assigning output from a executable to a variable in my script as so:

data=`$XM list -l | sed s/\(//g | sed s/\)//g`; #strip parens

I want to pull out lines matching:

domid
cpu_time

from $data, but I can't figure out exactly how to go about that via a regex.  As the input is not coming in via a file, I don't know how to grab one line at a time and I can't save the output temporarily to a file as that is one of my restrictions.  There are multiple occurrences of the below block in the output I need to parse and I don't know beforehand how many there will be.

How can I take this info and parse it into an array holding the tokens?  The tokens being defined as the line beginning with domid and the line beginning with cpu_time.  I'm under the impression that bash does not have multi-dimensional arrays so I have to store these in 2 arrays, right?

(domain
    (domid 14)
    (uuid 04500ade-a703-23b7-e6f8-31e41c588c00)
    (vcpus 1)
    (cpu_weight 1.0)
    (memory 160)
    (shadow_memory 0)
    (maxmem 160)
    (features )
    (name sampledomain.com)
    (on_poweroff destroy)
    (on_reboot restart)
    (on_crash destroy)
    (image
        (linux
            (kernel /home/users/sampledomain.com/linux)
            (root '/dev/xvda1 ro')
        )
    )
    (device
        (vif
            (backend 0)
            (script vif-bridge)
            (bridge xen-br0)
            (mac aa:00:79:64:33:ce)
        )
    )
    (device
        (vbd
            (backend 0)
            (dev xvda1:disk)
            (uname file:/home/users/sampledomain.com/fc6-1.ext3)
            (mode w)
        )
    )
    (device
        (vbd
            (backend 0)
            (dev xvda9:disk)
            (uname file:/home/users/sampledomain.com/swapfs.swp)
            (mode w)
        )
    )
    (state -b----)
    (shutdown_reason poweroff)
    (cpu_time 20205.5002826)
    (online_vcpus 1)
    (up_time 3047639.48897)
    (start_time 1171852894.06)
)
lomidienAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

JaaxArchitectCommented:
Your regex would be /[^[domain][cpu_time]]/
0
lomidienAuthor Commented:
The line that I'm parsing is the line above, but with 10-50 repetitions.  There are no line endings because I've stripped \n using sed.  How can I apply the above to tokenize entries of:

domid & cpu_time

and stuff them into an array(s) so that I can retried them like:

dom[n] & cpu[n]

It may be that I'm going about this wrong, I'm not sure, but I'm trying to put this in a bash script like so:

(irrelevant lines stripped)

#!/bin/bash

#SCRIPT VARIABLES
XM="/usr/sbin/xm"; #location of xm executable

#GRAB CURRENT XEN STATISTICS (PARENS & \n STRIPPED)
data=`$XM list -l | sed s/\(//g | sed s/\)//g`;

#i want to iterate over the input (like the above block) and pull
#substrings matching "domid NUMBER" and "cpu_time NUMBER" and 'tokenize'
#those into an array here

exit

I hope that this is clear, I'm a java programmer by nature and bash scripting isn't exactly my forte. :)
0
ozoCommented:
dom=(`$XM list -l | sed s/\(//g | sed s/\)//g | grep domid`)
cpu=(`$XM list -l | sed s/\(//g | sed s/\)//g | grep cpu_time`)
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

lomidienAuthor Commented:
ozo:

That works assuming that there is only 1 block like I posted.  The input consists of this block repeated as many as 50 times and I need to pull out each match.  I want to stuff the matching portions into an array where each element will hold a single matching entry.

Thanks,
David
0
ozoCommented:
dom=(`$XM list -l | sed s/\(//g | sed s/\)//g | grep domid`) does stuff the matching portions into an array where each element will hold a single matching entry.
echo ${dom[0]} would show the first entry ${dom[*]} would show all ig them
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MehugeCommented:
# Assumes well formatted input
$XM list -l  | awk > /tmp/blah$$ '
    /^[     ]*\(domid/ {
        gsub("\\(",""); gsub(")","");
        id="domid[" n++ "]=" $2;
    }
    /^[     ]*\(cpu_time / {
        gsub("\\(",""); gsub(")","");
        time="cpu_time[" n "]=" $2;
    }
    /^[     ]*\(domain/ && id != "" {
        print id "; " time;
        id=""; time="";
    }
    END {
        if (id != "") {
            print id "; " time;
        }
    }
    '
. /tmp/blah$$

echo ${domid[0]} etc.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Shell Scripting

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.