Как я могу извлечь записи A, которые также имеют записи TXT в Perl? - PullRequest
2 голосов
/ 25 января 2010

У меня есть такие данные:

uniqname1.foo.bar IN A 10.0.0.1  
uniqname1.foo.bar IN TXT "abcdefg"  
uniqname2.foo.bar IN A 10.0.0.2  
uniqname2.foo.bar IN TXT "xyz"  
uniqname3.foo.bar IN A 10.0.0.3  
uniqname4.foo.bar IN A 10.0.0.4`

Вы получаете картину, не у каждого хоста есть TXT, у некоторых есть. Я пытаюсь получить регулярное выражение, которое будет выводить 3 значения для хостов, которые имеют TXT, в этом случае вывод будет:

uniqname1.foo.bar 10.0.0.1 abcdefg  
uniqname2.foo.bar 10.0.0.2 xyz`

Ответы [ 4 ]

2 голосов
/ 25 января 2010

Я бы не использовал для этого регулярное выражение. Скорее всего, вы столкнетесь с некоторыми файлами, которые имеют вещи в другом порядке, полностью испортив ваш шаблон. Вместо этого создайте структуру данных для хранения записей, выберите записи с записями TXT и из записей TXT найдите данные A. Хотя регулярные выражения забавны и мощны, хэши иногда даже мощнее:

use 5.010;

while( <DATA> ) {
    chomp;
    # maybe another normalization step here
    my( $name, undef, $type, $data ) = split;

    $records{$type}{$name} = $data;
    }

foreach my $txt_record ( keys %{ $records{'TXT'} } ) {
    my $txt_data = $records{'TXT'}{$txt_record};
    my $a_data   = $records{'A'}{$txt_record};

    say join ' ', $txt_record, $a_data, $txt_data;
    }

__DATA__
uniqname1.foo.bar IN A 10.0.0.1
uniqname1.foo.bar IN TXT "abcdefg"
uniqname2.foo.bar IN A 10.0.0.2
uniqname2.foo.bar IN TXT "xyz"
uniqname3.foo.bar IN A 10.0.0.3
uniqname4.foo.bar IN A 10.0.0.4
0 голосов
/ 26 января 2010

другой способ

#!/usr/bin/perl
while (<>) {
    @F = split ' ', $_ ;
    if ($F[2] eq 'A') {
        $a{$F[0]} = $a{$F[0]} . ' ' . $F[$#F];
    }
    if ($F[2] eq 'TXT') {
        print "$F[0] $a{$F[0]} $F[$#F] \n";
    }
}

выход

$ perl test.pl file
uniqname1.foo.bar  10.0.0.1 "abcdefg"
uniqname2.foo.bar  10.0.0.2 "xyz"
0 голосов
/ 25 января 2010

Вам действительно нужно проанализировать данные текстовой зоны? Почему бы не запросить эти данные программно с помощью Net :: DNS ?

Например:

use Net::DNS;
my $res = Net::DNS::Resolver->new;
my $txtquery = $res->query("example.com", "TXT");
my $aquery = $res->query("example.com", "A");

if ($txtquery and $aquery) {
    ($txtquery->answer)[0]->print;
} else {
    print "query failed: ", $res->errorstring, "\n";
}
0 голосов
/ 25 января 2010

В perl:

while ($s =~ m/^([\w.]+) IN A ([\d.]+)(?:\r|\r\n|\n)$1 IN TXT "([\w+])"/m) {
    print "$1 $2 $3\n";
}

Где $ s - это ваш блок данных, который у вас есть выше.

Я не проверял, но вышесказанное близко.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...