简体   繁体   English

在Linux中解析

[英]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 我想解析结果如下,仅采用具有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;;

In Perl (and written rather more verbosely than is really necessary): 在Perl中(并且写得比实际需要的还要冗长):

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

my $node; # Store current node name
my @compute_nodes; # Store known nova-compute nodes

while (<>) { # Read from STDIN
  # If we find the start of line, followed by a pipe, a space and
  # a series of word characters...
  if (/^\| (\w+)/) {
    # Store the series of word characters (i.e. the node name) in $node
    $node = $1;
  }

  # If we find a line that contains "nova-compute", add the current
  # node name in @compute_nodes
  push @compute_nodes, $node if /nova-compute/;
}

# Print out all of the values in @compute_nodes    
say join ';', @compute_nodes;

I detest one-line programs except for the most simple of applications. 除了最简单的应用程序之外,我讨厌一线程序。 They are unnecessarily cryptic, they have none of the usual programming support, and they are stored only in the terminal buffer. 它们不必要地是加密的,没有通常的编程支持,并且仅存储在终端缓冲区中。 Want to do the same thing tomorrow? 想明天做同样的事情吗? You must start coding again 您必须重新开始编码

Here's a Perl solution. 这是一个Perl解决方案。 Run it as 运行为

$ perl nova-compute.pl command-output.txt
use strict;
use warnings 'all';

my ($node, @nodes);

while ( <> ) {
    $node = $1 if /^ \| \s* (\w+) /x;
    push @nodes, $node if /nova-compute/;
}

print join(';', @nodes), "\n";

output 输出

Compute01;Compute02

Now all of that is saved on disk. 现在所有这些都保存在磁盘上。 It may be run again at any time, modified for similar results, or fixed if you got it wrong. 它可能会在任何时间再次运行,为获得类似结果而进行修改,或者如果发现错误可以进行修复。 It is also readable. 它也是可读的。 No contest 没有比赛

$  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 . 如果node为非空并且当前行包含nova-compute ,则将node附加到字符串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 ; 阅读完所有行后,打印出字符串s减去多余的第一个字符; .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM