Есть файл dhcpd.conf
содержит блоки текста вида:
host 192.168.1.98 {
hardware ethernet 00:50:22:b0:39:c7;
fixed-address 192.168.1.98;
}
host 192.168.1.99 {
hardware ethernet 00:50:02:e0:00:17;
fixed-address 192.168.1.99;
}
......... и т.д.скрип:
open (prt, "<dhcpd.conf");
while($dd=<prt>){
($name, $adr, $mac)=$dd =~ m/(192.168.1.\d+)((\w+:){5}\w+)(192.168.1.\d+)/;
print "$name $adr $mac\n";
};
разумеется данный скрипт в таком виде ничего не выводит.
цель, получить вывод вида:
192.168.1.98 00:50:22:b0:39:c7 192.168.1.98
192.168.1.99 00:50:02:e0:00:17 192.168.1.99
......
вопрос: как объединить строки в абзацы?
host 192.168.1.98 {
hardware ethernet 00:50:22:b0:39:c7;
fixed-address 192.168.1.98;
}
......
Одно из двух
1) читать построчно, проверять на три разных регекса
2) читать весь файл сразу и проверять одним регексом
А у вас читается построчно и попытка применить регекс части которого относятся к разным строкам. Разумеется он ничего не найдет
>цель, получить вывод вида:
>192.168.1.98 00:50:22:b0:39:c7 192.168.1.98
>192.168.1.99 00:50:02:e0:00:17 192.168.1.99#!/usr/bin/perl -w
use strict;
#разделитель сторок, если ставим просто "}" то в конце читается еще одна - пустая строка
$/ ="}\x0A";
my $dd;
my $name_shabl = '[^\s]+'; #что бы имя не было только IP
my $ip_shabl = '\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}';
my $mac_shabl = '([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}';
#my $parse_regx = "host\\s+($ip_shabl)\\s+.+ethernet\\s+($mac_shabl)\\s*;.+fixed-address\\s+($ip_shabl);";
my $parse_regx = "host\\s+($name_shabl)\\s+.+ethernet\\s+($mac_shabl)\\s*;.+fixed-address\\s+($ip_shabl)\\s*;";my ($name, $addr, $mac);
open (PRT, "<", "dhcpd.conf");
#print "search shablon: $parse_regx\n";
while($dd = <PRT>){
$dd =~ s/\x0A//g;
#print "read: '$dd'\n";
if($dd =~ m/$parse_regx/g) {
$name = $1;
$mac = $2;
$addr = $4;
print "$name $mac $addr\n";
#print "$mac $addr\n";
} else {
print "undefined format\n";
}
};
close PRT;
[admin@comm perl]$ ls -l dh*
-rw-r--r-- 1 admin wheel 193 Окт 8 12:50 dhcpd.conf
-rwxr-xr-x 1 admin wheel 576 Окт 8 12:46 dhcp_parse
[admin@comm perl]$
[admin@comm perl]$ cat ./dhcpd.conf
host 192.168.1.98 {
hardware ethernet 00:50:22:b0:39:c7;
fixed-address 192.168.1.98;
}
host 192.168.1.99 {
fixed-address 192.168.1.99;hardware ethernet 00:50:02:e0:00:17;
}[admin@comm perl]$ ./dhcp_parse
192.168.1.98 00:50:22:b0:39:c7 192.168.1.98
192.168.1.99 00:50:02:e0:00:17 192.168.1.99
[admin@comm perl]$
[admin@comm perl]$ cat ./dhcp_parse
#!/usr/bin/perl
use strict;
use warnings;
use vars qw( $config %hosts );
sub parse_host_record($$);undef $/;
open(F, '<', 'dhcpd.conf') or die($!);
$config = <F>;
close( F );parse_host_record( $1, $2 ) while $config =~ /\b host \s+ (\S+) \s* { ([^}]+) } /gsix;
foreach my $key ( sort keys %hosts ) {
printf( "%s %s %s\n", $key, $hosts{$key}{'hardware ethernet'}, $hosts{$key}{'fixed-address'} );
}sub parse_host_record($$) {
my( $host, $params );
( $host, $params ) = @_;
$hosts{$host}{$1} = $2 while $params =~ / \s* (.+?) \s+ (\S+) \s* ; /gsix;
}
Большое спасибо!
Разобрался со скриптом.
Вопрос возник только с одной вещью:
$/ ="}\x0A";$/ - описание что-то не нашел
\x0A - шестнадцатеричная, но почему именно 0A
>$/ - описание что-то не нашелman perlvar. Это переменая указывает что является разделителем для для строк. В данном скрипте это } плюс конец строки
>\x0A - шестнадцатеричная, но почему именно 0Aстандартный символ окончания строки в линуксе, также зачастую обозначается как \n. Если файл имеет dos/win формат, то это будет \r\n или \x0D\x0A, для мака - \x0D.
>
>>$/ - описание что-то не нашел
>
>man perlvar. Это переменая указывает что является разделителем для для строк. В
>данном скрипте это } плюс конец строки
>>\x0A - шестнадцатеричная, но почему именно 0A
>
>стандартный символ окончания строки в линуксе, также зачастую обозначается как \n. Если
>файл имеет dos/win формат, то это будет \r\n или \x0D\x0A, для
>мака - \x0D.Спасибо, разобрался