Добрый день.имеем 2 файла вида:
$cat host
<host>host1.fullname</host>
<ip>721.0.0.1</ip>
<name>host1.shortname</name>
<proxy>
<name>proxy1.fullname</name>
</proxy>
--
<host>host2.fullname</host>
<ip>721.0.0.2</ip>
<name>host2.shortname</name>
<proxy>
<name>proxy2.fullname</name>
</proxy>
--
...
$cat ip
<group>
<name>GROUP1</name>
<name>GROUP2</name>
</group>
<ip>721.0.0.1</ip>
<dns>host1.fullname</dns>
--
<group>
<name>GROUP3</name>
<name>GROUP4</name>
</group>
<ip>721.0.0.2</ip>
<dns>host2.fullname</dns>
--
...как выводить мне из двух файлов скриптом следующее
--
hostname: host1.fullname
ip: 721.0.0.1
short: host1.shortname
proxy: proxy1.fullname
group: GROUP1 , GROUP2
--
hostname: host2.fullname
ip: 721.0.0.2
short: host2.shortname
proxy: proxy2.fullname
group: GROUP1 , GROUP2только есть один нюанс, если в файле ip в секции
<group>
<name>GROUP1</name>
<name>GROUP1</name>
</group>
GROUP1=GROUP1 то вывод
--
hostname: host1.fullname
ip: 721.0.0.1
short: host1.shortname
proxy: proxy1.fullname
group: GROUP1есть у кого идеи? может кто делал такое!!
Спасибо.
вот прям реально такие файлы?
XML поломанный
> вот прям реально такие файлы?
> XML поломанныйда. именно такие.
> Добрый день.
> имеем 2 файла вида:за подобный формат файлов нужно бить табуреткой по голове до просветления.
> как выводить мне из двух файлов скриптом следующее
> short: host1.shortnameоткуда вообще взялся данный тег?
> только есть один нюанс, если в файле ip в секции
>
> <group>
> <name>GROUP1</name>
> <name>GROUP1</name>
> </group>
> GROUP1=GROUP1 то выводесли у тебя два тега с одинаковыми данными, то да данные этих тегов одинаковы, что ты хотел сказать?
> есть у кого идеи? может кто делал такое!!
нанять человека который сможет хотя бы внятно объяснить что он хочет
>> Добрый день.
>> имеем 2 файла вида:
> за подобный формат файлов нужно бить табуреткой по голове до просветления.это парсился xml и из него выбиратось то что нужно.
>> как выводить мне из двух файлов скриптом следующее
>> short: host1.shortname
> откуда вообще взялся данный тег?это условное название
test.hostname.su (full)
test (short)>> только есть один нюанс, если в файле ip в секции
>>
>> <group>
>> <name>GROUP1</name>
>> <name>GROUP1</name>
>> </group>
>> GROUP1=GROUP1 то вывод
> если у тебя два тега с одинаковыми данными, то да данные этих
> тегов одинаковы, что ты хотел сказать?есть такой тег как group в нем от 1 до двух name как ниже
<group>
<name>GROUP1</name>
<name>GROUP2</name>
</group>
при таком раскладе выводим group : GROUP1, GROUP2, но если в группе
<name>GROUP1</name>
<name>GROUP1</name>
оба параметра идентичны то выводим только group: GROUP1>> есть у кого идеи? может кто делал такое!!
> нанять человека который сможет хотя бы внятно объяснить что он хочетпримерно так!!
в файлах позиции одинаковые тоесть 1 секция в первом файле соответствует 1 секции во втором.
> это парсился xml и из него выбиратось то что нужно.Шта-а-а?? Whiskey Tango Foxtrot ??
может лучше сразу из xml парсить правильно и то что нужно?
а то парсим, потом ещё раз парсим! WTF!?н-да, однако, вы знаете толк в извращениях )))
> в файлах позиции одинаковые тоесть 1 секция в первом файле соответствует 1
> секции во втором.секции, позиции, и т.д. - ну нихера ж не понятно...
Михалыч прально сказал - парси исходный XML, а не дергай из него невнятные куски с непонятной корреляцией данных, чтобы потом героически изобретать велосипед, который ты походу еще и не знаешь как устроен.
>[оверквотинг удален]
> </group>
> GROUP1=GROUP1 то вывод
> --
> hostname: host1.fullname
> ip: 721.0.0.1
> short: host1.shortname
> proxy: proxy1.fullname
> group: GROUP1
> есть у кого идеи? может кто делал такое!!
> Спасибо.я так понимаю что сопоставление сущностей в двух файлах идет в порядке их описания в файлах?
а разделение блоков сущностей происходит символами "--" ?
ну... складываете содержимое файл в массив по разделителю "--", организуете цикл по массиву, в котором у вас теперь элемент - это сущность, делаете примитивный парсер тэгов и сопоставляете нужное.
>[оверквотинг удален]
>> --
>> hostname: host1.fullname
>> ip: 721.0.0.1
>> short: host1.shortname
>> proxy: proxy1.fullname
>> group: GROUP1
>> есть у кого идеи? может кто делал такое!!
>> Спасибо.
> я так понимаю что сопоставление сущностей в двух файлах идет в
> порядке их описания в файлах?да
> а разделение блоков сущностей происходит символами "--" ?да
> ну... складываете содержимое файл в массив по разделителю "--", организуете цикл
> по массиву, в котором у вас теперь элемент - это сущность,
> делаете примитивный парсер тэгов и сопоставляете нужное.этими параметрами указываем на привязку 1 файла ко 2-му!!
<name>host1.fullname</name>
--
<dns>host1.fullname</dns>
ну, что же..
я ждал, но первозданный XML файл так и не показываютладно, обойдёмся ))
погнали
#!/usr/bin/perluse strict;
use warnings;
my $host = "host";
my $ip = "ip";open ( FH1, $host ) or die "couldn't open $host : $!";
open ( FH2, $ip ) or die "couldn't open $ip : $!";
my (@hostname, @addr, @short, @proxy, @group, %unic);{ local $/ = undef;
while ( <FH1> ) {
@hostname = m|<host>(.*)</host>|g;
@addr = m|<ip>(.*)</ip>|g;
@short = m|<name>(.*)</name>|g;
@proxy = m|<proxy>.*?>(.*?)</.*?</proxy>|gs;
}
}my $count = 0;
while ( <FH2> ) {$count++ if /--/;
if (m|<name>(.*)</name>|) {push @{$group[$count]}, $1 unless $unic{$1}++;}
}close FH1;
close FH2;for (my $i=0; $i<@addr; $i++) {
print "--\n";
print "hostname: $hostname[$i]\n";
print "ip: $addr[$i]\n";
print "short: $short[$i]\n";
print "proxy: $proxy[$i]\n";
print "group: ", join(", ", @{$group[$i]}),"\n";
}комментарии писать лень, и так всё понятно )))
да, можно пойти по пути предложенному ыы
#!/usr/bin/perluse strict;
use warnings;
undef $/;my $host = "host";
my $ip = "ip";open ( FH1, $host ) or die "couldn't open $host : $!";
open ( FH2, $ip ) or die "couldn't open $ip : $!";
my @hosts = split(/--/, <FH1>);
my @ips = split(/--/, <FH2>);close FH1;
close FH2;my (@hostname, @addr, @short, @proxy, @group, %unic);
for (my $i=0; $i<@hosts; $i++) {
$hosts[$i] =~ m|<host>(.*)</host>|;
push @hostname, $1;$hosts[$i] =~ m|<ip>(.*)</ip>|;
push @addr, $1;$hosts[$i] =~ m|<name>(.*)</name>|;
push @short, $1;$hosts[$i] =~ m|<proxy>.*>(.*)<.*</proxy>|s;
push @proxy, $1;if ($ips[$i] =~ m|<group>.*?>(.*?)<.*?</group>|s) {push @{$group[$i]}, $1 unless $unic{$1}++;}
if ($ips[$i] =~ m|<group>.*>(.*)<.*</group>|s) {push @{$group[$i]}, $1 unless $unic{$1}++;}}
for (my $i=0; $i<$#hosts; $i++) {
print "--\n";
print "hostname: $hostname[$i]\n";
print "ip: $addr[$i]\n";
print "short: $short[$i]\n";
print "proxy: $proxy[$i]\n";
print "group: ", join(", ", @{$group[$i]}),"\n";
}но есть нюанс )))
цикл while vs цикл forвспомнился бородатый анекдот про нюанс http://bfy.tw/IvBU
это что так препод садист изголяется??
ух он какой, у-у-ууу..ps
конечно, цикл for можно переписать по другому, более компактноfor (my $i=0; $i<@hosts; $i++) {
push @hostname, $1 if $hosts[$i] =~ m|<host>(.*)</host>|;
push @addr, $1 if $hosts[$i] =~ m|<ip>(.*)</ip>|;
push @short, $1 if $hosts[$i] =~ m|<name>(.*)</name>|;
push @proxy, $1 if $hosts[$i] =~ m|<proxy>.*>(.*)<.*</proxy>|s;if ($ips[$i] =~ m|<group>.*?>(.*?)<.*?</group>|s) {push @{$group[$i]}, $1 unless $unic{$1}++;}
if ($ips[$i] =~ m|<group>.*>(.*)<.*</group>|s) {push @{$group[$i]}, $1 unless $unic{$1}++;}}
такие дела
Зачем вуду-магия крестянам, Михалыч? Есть же XML парсеры в перле, если не может осилить то онанизм с регексами вокруг XML - это путь в никуда.
> Зачем вуду-магия крестянам, Михалыч? Есть же XML парсеры в перле, если не
> может осилить то онанизм с регексами вокруг XML - это путь
> в никуда.да ладно, что там!
я ж так, для собственного удовольствия ))видал, тут вообще аноним почти в две строчки уложился, о как!
ну прикольно же!оно, конечно, может ты и прав, есть и модули для XML
хотя и с ними не всё так просто и однозначно,но с другой стороны - с регулярками не надо парится,
это как раз на себя и берут эти парсеры (модули)но ТС зажал исходный XML
а если мы предоставленные файлы возьмём да и чуть-чуть поправим !?
не ну а что? имеет право быть!
сам поломал - сам и починил (но это не точно ))))
#!/usr/bin/perluse strict;
use warnings;
use XML::LibXML;
use File::Temp qw(tempfile);
my $host = "host";
my $ip = "ip";## объявляем массивы для складирования готовой продукции ))
my (@hostname, @addr, @short, @proxy, @group, %unic);## вспомогательные массивы
my (@f, @f_pre, @f1, @f2);open ( FH1, $host ) or die "couldn't open $host : $!";
open ( FH2, $ip ) or die "couldn't open $ip : $!";
## исправляем синтаксис XML файлов и сливаем их в один
{local $/ = undef;while (<FH1>){
s|--|</tag>\n<tag>|g;
@f1 = m|(.*)|s;
}while (<FH2>){
s|(.*)--|$1</tag>\n</f>|s;
s|--|</tag>\n<tag>|g;
@f2 = m|(.*)|s;
}
}close FH1;
close FH2;
@f_pre = ("<f>\n<tag>\n");
@f = (@f_pre, @f1, @f2);## это то, что и будем скармливать модулю XML::LibXML
#print "\n\tthis is a dirty corrected version of the xml file\n\n", @f, "\n\tEOF\n\n\n";
## создаём временный манипулятор и файл (при выходе удаляем его)
my ($fh, $file) = tempfile(UNLINK => 1);open $fh, ">", $file;
print $fh @f;
close $fh;
## теперь делаем вещи с помощью XPath и метода findnodesmy $parser = XML::LibXML->new;
my $doc = $parser->parse_file("$file");my @hostnames = $doc->findnodes("/f/tag/host");
foreach my $hn (@hostnames) {
push @hostname, $hn->firstChild->data;
}my @addrs = $doc->findnodes("/f/tag/ip");
foreach my $ad (@addrs) {
push @addr, $ad->firstChild->data;
}my @shorts = $doc->findnodes("/f/tag/name");
foreach my $sh (@shorts) {
push @short, $sh->firstChild->data;
}my @proxys = $doc->findnodes("/f/tag/proxy/name");
foreach my $pr (@proxys) {
push @proxy, $pr->firstChild->data;
}for (my $i=0; $i<@hostname; $i++) {
my @groups = $doc->findnodes("/f/tag/
dns[text()='$hostname[$i]']/
../group/name/text()");foreach my $gr (@groups) {
push @{$group[$i]}, $gr->data unless $unic{$gr->data}++;}
}
for (my $i=0; $i<@hostname; $i++) {print "--\n";
print "hostname: $hostname[$i]\n";
print "ip: $addr[$i]\n";
print "short: $short[$i]\n";
print "proxy: $proxy[$i]\n";
print "group: ", join(", ", @{$group[$i]}),"\n";
}да, блин, в попугаях получилось длиннее (((
#!/usr/bin/perlmy $hosts = {};
my $ips = {};for( do{ local $/ = "--"; <STDIN> } ){
next unless( my( $ip ) = m/<ip>([^<]+)/ );
if(/<group>/){
$ips->{$ip} = { map { $_ => 0 } m/<name>([^<]+)/g } ;
next ;
}
$hosts->{$ip} = [ m/<host>([^<]+).*<name>([^<]+)/s ];
}for my $ip ( sort{ $hosts->{$a}->[0] cmp $hosts->{$b}->[0] } keys %$hosts ){
my( $short, $long ) = @{ $hosts->{$ip} };
printf qq|hostname: %s\nip: %s\nshort: %s\nproxy: %s\ngroup: %s\n--\n|,
$long, $ip, $short, $long, join(", ", sort keys %{ $ips->{$ip} });
}
Пользоваться
cat host ip | perl script.pl
браво, бис!
мастер-класс, да и только.