美好的一天。
很抱歉这个问题的标题,但我很难解释这一点。
我有一个类似这样的文件(数百台服务器)
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
预先感谢一些亮点!
答案 0 :(得分:3)
@ARGV
是给出的参数,因此,在您./find_parent_server.pl container10
的情况下,container10
中可以找到$ARGV[0]
。 shift
关闭它允许使用神奇的<>
,它从STDIN读取或提供文件名。
use feature qw{ say } ;
use strict ;
use warnings ;
my $input = shift
or die("usage\n") ;
my $host = '' ;
my $virt = '' ;
while (<>) {
chomp ;
elsif (m{([^-\s]\S*)}) {
$host = $1;
next if $host ne $input;
say $host ;
}
elsif (m{^--\s*([^-\s]\S*)}) {
$virt = $1;
next if $virt ne $input;
say $host ;
say "-- $virt" ;
}
elsif (m{^----\s*([^-\s]\S*)}) {
my $container = $1;
next if $container ne $input;
say $host ;
say "-- $virt" ;
say "---- $container" ;
}
}
如果您的名字中包含空格,请将[^-\s]\S*
替换为[^-\s].*
。
答案 1 :(得分:3)
这是一个直接回答您问题的程序
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",
}
答案 2 :(得分:2)
可能用正则表达式 -
来做 # (?ms)(?|^($item)()()|^(\w+)(?:(?!^\w).)*?^(--\h*$item)()|^(\w+)(?:(?!^\w).)*^(--\h*\w+)(?:(?!^\w).)*?^(----\h*$item))
(?ms)
(?|
^
( $item ) # (1)
( ) # (2)
( ) # (3)
|
^
( \w+ ) # (1)
(?:
(?! ^ \w )
.
)*?
^
( -- \h* $item ) # (2)
( ) # (3)
|
^
( \w+ ) # (1)
(?:
(?! ^ \w )
.
)*
^
( -- \h* \w+ ) # (2)
(?:
(?! ^ \w )
.
)*?
^
( ---- \h* $item ) # (3)
)
Perl片段:
use strict;
use warnings;
$/ = undef;
my $servers = <DATA>;
my @ary = ( 'container10', 'virtualserver4', 'mainserver1');
foreach my $item ( @ary )
{
if ( $servers =~ /(?ms)(?|^($item)()()|^(\w+)(?:(?!^\w).)*?^(--\h*$item)()|^(\w+)(?:(?!^\w).)*^(--\h*\w+)(?:(?!^\w).)*?^(----\h*$item))/ )
{
print "Found '$item' :\n";
print "$1\n" if (length($1));
print "$2\n" if (length($2));
print "$3\n" if (length($3));
print "\n";
}
}
__DATA__
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
输出:
Found 'container10' :
mainserver1
-- virtualserver4
---- container10
Found 'virtualserver4' :
mainserver1
-- virtualserver4
Found 'mainserver1' :
mainserver1
答案 3 :(得分:1)
将其存储在树形结构中的哈希值中,然后根据您的需要进行打印。小心library(data.table)#v1.9.5+
setDT(Test)[, Best_Bid_Ex:= Bid[1L], rleid(!is.na(Tick))]
Test
# Tick Bid Best_Bid_Ex
# 1: NA 393.75 393.75
# 2: NA 393.75 393.75
# 3: NA 393.75 393.75
# 4: NA 394 393.75
# 5: NA 394 393.75
# 6: 1 NA NA
# 7: NA 394 394
# 8: NA 394 394
# 9: NA 394 394
#10: NA 394 394
#11: NA 393.75 394
#12: -1 NA NA
#13: NA 393.75 393.75
#14: NA 393.75 393.75
和--
,即你不应该在那里放置额外的空格。
----
像
一样使用它#!/usr/bin/perl
use strict;
use warnings;
my %hash = ();
my $key1;
my $key2;
while ( <DATA> ) {
chomp;
if ( /^[a-z]+/ ) {
$key1 = $_;
$hash{$key1} = {};
}
if ( /^--[a-z]+/ ) {
$key2 = $_;
$key2 =~ s/--//g;
$hash{$key1}{$key2} = [];
}
if ( /^---- [a-z]+/ ) {
$_ =~ s/---- //g;
push( @{ $hash{$key1}{$key2} }, $_ );
}
}
my $server = $ARGV[0];
my $flag = 0;
foreach my $key ( keys %hash ) {
foreach my $nkey ( keys %{ $hash{$key} } ) {
if ( $server eq $nkey ) {
$flag = 1;
print "$key \n--$server \n";
last;
}
elsif ( grep { $server eq $_ } @{ $hash{$key}{$nkey} } ) {
$flag = 1;
print "$key \n--$nkey \n---- $server \n";
last;
}
}
}
print "Oops!! No Such server \n" if ( $flag == 0 );
__DATA__
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
输出:
perl script.pl container10
答案 4 :(得分:0)
用sed解决方案。 (是的,它很难看,但有效)
(read -p "Search term: " servername;tac list_of_servertree.txt |sed -n "/$servername$/,/^[a-z]/p"|tr '\n' ' ';echo)|sed -e 's/\([^\-]\)\ \([a-zA-Z]\)/\1\n\2/1' -e 's/\(^\|\ \)\(--\ \{0,1\}[a-zA-Z]\)/\n\2/1' |sed 's/^\(-\+[^\-]\+\).*/\1/g'|grep -v '^$'
答案 5 :(得分:0)
受@ sln正则表达式解决方案的启发。
T=container10 perl -0777 -ne
'print/.*(^\w\S+.)(?:.*^(--\w\S+.).*?^(---- )|.*?^(--))($ENV{T}\b.)/ms' server.list
捕获组对应于您想要的输入。贪婪的.*
表达式会占用您不想要的所有输入,并且在目标表达式之前使用非贪婪的.*?
。