1

文件services- 包含许多这样的记录:

define service {
    host_name\t\t\t\tHOSTNAME
    ...
    ...
}

文件hosts- 包含记录:

define host {
    host_name\t\t\t\tHOSTNAME
    ...
    ...
}

我需要去hosts,以某种方式从第一条记录中获取主机名的名称,然后转到文件services并找到具有该主机名的所有记录并将它们放入其他文件。然后对hosts.

我不知道主要如何从文件主机获取 HOSTNAME,然后如何将文件服务中的整个记录​​获取到变量中。我准备了一个正则表达式(希望是对的)^define.*host_name\t\t\t\t$HOSTNAME.*}

请给我一些建议或示例如何获得想要的结果。

4

2 回答 2

3

您提供的文件看起来很像 nagios 配置文件。

sed 在这里可能是您的朋友,因为它允许您将文件切成更小的部分,例如:

:t
/^define service {/,/}$/ {    # For each line between these block markers..
   /}$/!{         #   If we are not at the /end/ marker
      $!{          #     nor the last line of the file,
         N;        #     add the Next line to the pattern space
         bt
      }            #   branch (loop back) to the :t label.
   }               # This line matches the /end/ marker.
   /host_name[ \t]\+HOSTNAME\b/!d;       # delete the block if wrong host.
}

该示例从 sed faq 4.21 中提取,并稍作调整。您还可以查看问题 4.22,它似乎直接解决了这个问题:

http://sed.sourceforge.net/sedfaq4.html#s4.22

与前面的答案一样,我也倾向于说您最好使用另一种脚本语言。如果您无论如何都需要一个不同的解释器来完成这项工作,不妨使用您知道的东西。

于 2013-04-19T12:01:15.130 回答
2

这个任务对于 bash 脚本来说有点太复杂了。我会使用 Perl:

#!/usr/bin/perl
use warnings;
use strict;

open my $SRV, '<', 'services' or die $!;
open my $HST, '<', 'hosts'    or die $!;

my %services;
{    local $/ = "\n}";
     while (my $service = <$SRV>) {
         my ($hostname) = $service =~ /^\s*host_name\t+(.+?)\s*$/m;
         push @{ $services{$hostname} }, $service if defined $hostname;
     }
 }

while (my $line = <$HST>) {
    if (my ($host) = $line =~ /^\s*host_name\t+(.+?)\s*$/) {
        if (exists $services{$host}) {
            print "===== $host =====\n";
            print "$_\n" for @{ $services{$host} };
        } else {
            warn "$host not found in services!\n";
        }
    }
}
于 2013-04-19T10:52:33.127 回答