Dipak Dipak - 4 months ago 7
Perl Question

Parsing in linux

Problem:
i want to parse the compute zones in open-stack command output as blow

+-----------------------+----------------------------------------+
| Name | Status |
+-----------------------+----------------------------------------+
| internal | available |
| |- controller | |
| | |- nova-conductor | enabled :-) 2016-07-07T08:09:57.000000 |
| | |- nova-consoleauth | enabled :-) 2016-07-07T08:10:01.000000 |
| | |- nova-scheduler | enabled :-) 2016-07-07T08:10:00.000000 |
| | |- nova-cert | enabled :-) 2016-07-07T08:10:00.000000 |
| Compute01 | available |
| |- compute01 | |
| | |- nova-compute | enabled :-) 2016-07-07T08:09:53.000000 |
| Compute02 | available |
| |- compute02 | |
| | |- nova-compute | enabled :-) 2016-07-07T08:10:00.000000 |
| nova | not available |
+-----------------------+----------------------------------------+


i want to parse the result as below, take only nodes having nova-compute

Compute01;Compute02


What i tried?
I used below command:

nova availability-zone-list | awk 'NR>2 {print $2}' | grep -v '|' | tr '\n' ';'


but it returns output as below:

;internal;Compute01;Compute02;nova;;


please help

Answer
$  nova availability-zone-list | awk '/^[|] [^|]/{node=$2} node && /nova-compute/ {s=s ";" node} END{print substr(s,2)}' 
Compute01;Compute02

How it works:

  • /^[|] [^|]/{node=$2}

    Any time a line begins with | followed by space followed by a character not |, then safe the second field as a node name.

  • node && /nova-compute/ {s=s ";" node}

    If node is non-empty and the current line contains nova-compute, then append node to the string s.

  • END{print substr(s,2)}

    After we have read all the lines, print out string s minus its first character which is a superfluous ;.

Comments