Search code examples
linuxperlshellparsingopenstack-nova

Parsing in Linux


I want to parse the compute zones in open-stack command output as below

+-----------------------+----------------------------------------+
| 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, taking only nodes having nova-compute

Compute01;Compute02

I used below command:

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

but it returns output like this

;internal;Compute01;Compute02;nova;;

Solution

  • $  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 save 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 ;.