The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



"разбор двух файлов"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Shell скрипты)
Изначальное сообщение [ Отслеживать ]

"разбор двух файлов"  +/
Сообщение от Андрей (??), 03-Июл-18, 15:27 
Добрый день.

имеем 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

есть у кого идеи? может кто делал такое!!
Спасибо.


Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "разбор двух файлов"  +/
Сообщение от михалыч (ok), 03-Июл-18, 17:54 
вот прям реально такие файлы?
XML поломанный
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

4. "разбор двух файлов"  +/
Сообщение от Андрей (??), 04-Июл-18, 15:06 
> вот прям реально такие файлы?
> XML поломанный

да. именно такие.

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

2. "разбор двух файлов"  +/
Сообщение от Pahanivo (ok), 04-Июл-18, 11:13 
> Добрый день.
> имеем 2 файла вида:

за подобный формат файлов нужно бить табуреткой по голове до просветления.

> как выводить мне из двух файлов скриптом следующее
> short: host1.shortname

откуда вообще взялся данный тег?

> только есть один нюанс, если в файле ip в секции
>            
>     <group>
>         <name>GROUP1</name>
>         <name>GROUP1</name>
>     </group>
> GROUP1=GROUP1 то вывод

если у тебя два тега с одинаковыми данными, то да данные этих тегов одинаковы, что ты хотел сказать?

> есть у кого идеи? может кто делал такое!!

нанять человека который сможет хотя бы внятно объяснить что он хочет

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

5. "разбор двух файлов"  +/
Сообщение от Андрей (??), 04-Июл-18, 15:20 
>> Добрый день.
>> имеем 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 секции во втором.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

7. "разбор двух файлов"  +/
Сообщение от михалыч (ok), 04-Июл-18, 18:24 
> это парсился xml и из него выбиратось то что нужно.

Шта-а-а?? Whiskey Tango Foxtrot ??

может лучше сразу из xml парсить правильно и то что нужно?
а то парсим, потом ещё раз парсим! WTF!?

н-да, однако, вы знаете толк в извращениях )))

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

8. "разбор двух файлов"  +/
Сообщение от Pahanivo (ok), 05-Июл-18, 09:30 
> в файлах позиции одинаковые тоесть 1 секция в первом файле соответствует 1
> секции во втором.

секции, позиции, и т.д. - ну нихера ж не понятно...
Михалыч прально сказал - парси исходный XML, а не дергай из него невнятные куски с непонятной корреляцией данных, чтобы потом героически изобретать велосипед, который ты походу еще и не знаешь как устроен.

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

3. "разбор двух файлов"  +/
Сообщение от ыы (?), 04-Июл-18, 11:48 
>[оверквотинг удален]
>     </group>
> GROUP1=GROUP1 то вывод
> --
> hostname: host1.fullname
> ip: 721.0.0.1
> short: host1.shortname
> proxy: proxy1.fullname
> group: GROUP1
> есть у кого идеи? может кто делал такое!!
> Спасибо.

я так понимаю что сопоставление сущностей в двух файлах  идет в порядке их описания в файлах?
а разделение блоков сущностей происходит символами "--" ?
ну... складываете содержимое  файл в массив по разделителю "--", организуете цикл по массиву, в котором у вас теперь элемент - это сущность, делаете примитивный парсер тэгов и сопоставляете нужное.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

6. "разбор двух файлов"  +/
Сообщение от Андрей (??), 04-Июл-18, 15:23 
>[оверквотинг удален]
>> --
>> 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>

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

9. "разбор двух файлов"  +/
Сообщение от михалыч (ok), 06-Июл-18, 16:30 
ну, что же..
я ждал, но первозданный XML файл так и не показывают

ладно, обойдёмся ))
погнали


#!/usr/bin/perl

use 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/perl

use 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}++;}

}

такие дела

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

10. "разбор двух файлов"  +/
Сообщение от Pahanivo (ok), 10-Июл-18, 11:36 
Зачем вуду-магия крестянам, Михалыч? Есть же XML парсеры в перле, если не может осилить то онанизм с регексами вокруг XML - это путь в никуда.
Ответить | Правка | ^ к родителю #9 | Наверх | Cообщить модератору

13. "разбор двух файлов"  +/
Сообщение от михалыч (ok), 10-Июл-18, 19:43 
> Зачем вуду-магия крестянам, Михалыч? Есть же XML парсеры в перле, если не
> может осилить то онанизм с регексами вокруг XML - это путь
> в никуда.

да ладно, что там!
я ж так, для собственного удовольствия ))

видал, тут вообще аноним почти в две строчки уложился, о как!
ну прикольно же!

оно, конечно, может ты и прав, есть и модули для XML
хотя и с ними не всё так просто и однозначно,

но с другой стороны - с регулярками не надо парится,
это как раз на себя и берут эти парсеры (модули)

но ТС зажал исходный XML

а если мы предоставленные файлы возьмём да и чуть-чуть поправим !?
не ну а что? имеет право быть!
сам поломал - сам и починил (но это не точно ))))


#!/usr/bin/perl

use 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 и метода findnodes

my $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";
}

да, блин, в попугаях получилось длиннее (((

Ответить | Правка | ^ к родителю #10 | Наверх | Cообщить модератору

11. "разбор двух файлов"  +1 +/
Сообщение от Аноним (11), 10-Июл-18, 18:48 
#!/usr/bin/perl

my $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

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

12. "разбор двух файлов"  +/
Сообщение от михалыч (ok), 10-Июл-18, 19:29 
браво, бис!
мастер-класс, да и только.
Ответить | Правка | ^ к родителю #11 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру