Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 772
  • Last Modified:

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)
)
0
lomidien
Asked:
lomidien
1 Solution
 
JaaxCommented:
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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
 
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

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now