regex - 找到一个作为模式给出的行词另一个行词,awk,perl,sed,grep?

标签 regex bash perl awk sed

美好的一天。

很抱歉这个问题的标题,但我很难解释这一点。

我有一个类似这样的文件(数百台服务器)

mainserver1
--virtualserver1
---- container1
---- container2
--virtualserver2
--virtualserver3
---- container3
---- container4
---- container5
-- virtualserver4
---- container6
---- container7
---- container8
---- container9
---- container10
---- container11
---- container12
---- container13
mainserver2
mainserver3
mainserver4
--virtualserver5
---- container14
---- container15
--virtualserver6
--virtualserver7
mainserver5
mainserver6

这意味着我有:

physicals servers
--virtual servers running on the physcal servers
---- containers (zones/dockers) running on virtual servers

名称可以不同,我以“--”、“----”和以 [a-z] 开头的物理主机作为指导。

正如您所注意到的,“--virtualserverx”之间没有空格,而“---- continerx”中有空格

我想查找某个服务器并获取父服务器。

预期输出

./find_parent_server.sh container10
mainserver1
--virtualserver4
---- container10

./find_parent_server.sh virtualserver4
mainserver1

./find_parent_server.sh mainserver1
mainserver1 is a Physical server (i think i can manage this)

有可能吗?

我尝试使用 grep,然后使用 perl,但没有按预期工作,但聊胜于无。

tac allservers | perl -lne 'print if /container10/ .. /^[a-z]/'
---- container10
---- container9
---- container8
---- container7
---- container6
-- virtualserver4
---- container5
---- container4
---- container3
--virtualserver3
--virtualserver2
---- container2
---- container1
--virtualserver1
mainserver1

一些光线将不胜感激,提前致谢!

最佳答案

更新

这是一个直接回答你问题的程序

use strict;
use warnings;

my $wanted = shift or die <<__USAGE__;
Usage:
    $0 <server name>

__USAGE__

my @ancestry;

open my $fh, '<', 'servers.txt' or die $!;

my $found;

while ( <$fh> ) {

  next unless / (-*) \s* (\S+) /x;
  my $index = length($1) / 2;
  $ancestry[$#ancestry = $index] = $2;

  if ( $2 eq $wanted ) {
    if ( @ancestry == 1 ) {
      printf "%s is a Physical server\n", $2;
    }
    else {
      printf "%s %s\n", '--' x $_, $ancestry[$_] for 0 .. $#ancestry;
    }
    ++$found;
    last;
  }
}

printf "Server %s is unknown\n", $wanted unless $found;

输出

>find_parent_server container10
 mainserver1
-- virtualserver4
---- container10

>find_parent_server virtualserver4
 mainserver1
-- virtualserver4

>find_parent_server mainserver1
mainserver1 is a Physical server

>find_parent_server container16
Server container16 is unknown

原创

这是一种使用您自己的数据构建将每个节点与其父节点相关联的散列的方法。它期望服务器文件作为命令行上的参数。如果您需要任何帮助来使用生成的哈希值,请说明

use strict;
use warnings;

my ( @ancestry, %parents );

while ( <> ) {
  next unless / (-*) \s* (\S+) /x;
  my $index = length($1) / 2;
  $ancestry[$#ancestry = $index] = $2;
  $parents{$2} = $index ? $ancestry[-2] : 'NONE';
}

use Data::Dump;
dd \%parents

输出

{
  container1     => "virtualserver1",
  container10    => "virtualserver4",
  container11    => "virtualserver4",
  container12    => "virtualserver4",
  container13    => "virtualserver4",
  container14    => "virtualserver5",
  container15    => "virtualserver5",
  container2     => "virtualserver1",
  container3     => "virtualserver3",
  container4     => "virtualserver3",
  container5     => "virtualserver3",
  container6     => "virtualserver4",
  container7     => "virtualserver4",
  container8     => "virtualserver4",
  container9     => "virtualserver4",
  mainserver1    => "NONE",
  mainserver2    => "NONE",
  mainserver3    => "NONE",
  mainserver4    => "NONE",
  mainserver5    => "NONE",
  mainserver6    => "NONE",
  virtualserver1 => "mainserver1",
  virtualserver2 => "mainserver1",
  virtualserver3 => "mainserver1",
  virtualserver4 => "mainserver1",
  virtualserver5 => "mainserver4",
  virtualserver6 => "mainserver4",
  virtualserver7 => "mainserver4",
}

关于regex - 找到一个作为模式给出的行词另一个行词,awk,perl,sed,grep?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31709824/

相关文章:

java - 使用android从字母数字字符串中提取数字

macos - 自动水印 - 文件夹操作

python - 将bashrc的环境变量加载到python中

mysql - 如何绑定(bind)值 INSERT INTO mysql perl

perl - Perl 中的美元符号加号?

python - 正则表达式中的灾难性回溯

java - XPath 中的循环?

regex - 如何从 Perl 字符串中删除特定字符?

bash - Forever List 不会显示在 Crontab 输出中,但会在从命令行运行时显示

perl - 如何使用您编写的 perl 模块?