Записки проperl

RSS-материал Записки проperl
Записки проperl - LiveJournal.com
Обновлено: 14 минут 25 секунд назад

Задачка

Ср, 01/25/2012 - 11:26
citeесть 2 бесконечно больших текстовых файла отсортированных лексикографически.br /Нужно найти разницу и записать в файлы./citebr /a name=cutid1/abr /precode open A, shift or die; open B, shift or die; my $h = 0; while (!(eof(A) eof(B)) ) { ( $a, $b ) = $h == 0 ? ( scalar lt;Agt;, scalar lt;Bgt; ) : $h == 1 ? ( $a, scalar lt;Bgt; ) : ( scalar lt;Agt;, $b ); print lt; $a and next unless (defined $b); print gt; $b and next unless (defined $a); $h = $a cmp $b or next; print $h == 1 ? gt; $b : lt; $a; } /code/prebr /в принципе, можно сократить 2 строчки, но было лень разбираться с code$h = $a cmp $b or next;/code...br /img src=http://arto.homeunix.org/cgi/track.pl?diff /br /a name=cutid1-end/a
Категории: Друзья

Look-Around Assertions в операторе s///

Пт, 01/20/2012 - 09:21
До сих пор не задумывался на эту тему, но работает. Пример:br /citeЗадание: Удалить все знаки «+», за которыми следует цифра./citebr /precode # perl -le $ARGV[0] =~ s#\+(?=\d)##g print $ARGV[0] +test + +12 +13 ++ +test + 12 13 ++ # /code/prebr /img src=http://arto.homeunix.org/images/psilocybin.jpg /
Категории: Друзья

Задачка про CIDR

Чт, 12/22/2011 - 09:35
a href=http://nponeccop.livejournal.com/225261.html?style=mineОтсюда/a:br /citeЗадача такова: есть ASCIIZ-строка с IP-адресом, надо вернуть true, если этот адрес попадает в один из диапазонов, перечисленных в файле.br /br /Файл текстовый такого формата,br /br /192.168.1.3,192.168.1.5br /192.168.2.4,193.0.0.3br /br /Файл не отсортирован, дипапазоны произвольные и могут пересекаться. Первый адрес меньше второго или равен ему. Пересечение диапазонов можно обрабатывать двумя путями: лиюо отказываться грузить такой файл и выдавать что с чем пересеклось, либо не отказываться и корректно работать в таких условиях.br /br /Файл грузится один раз и потом десятки миллионов раз лукапится. Записей в конфиге - сотни./citebr /a name=cutid1/abr /Решение:br /precode # cat gt; z.pl #! /usr/bin/perl use Net::Patricia; use Net::CIDR::Lite; my $pt = new Net::Patricia; my $cidr = new Net::CIDR::Lite; open F, shift or die; while (f) { chomp; s#,#-#; foreach my $m ($cidr-gt;add_range($_)-gt;list) { $pt-gt;add_string($m) } } foreach (lt;gt;) { chomp; print $_, :, $pt-gt;match_string($_) ? YES : NO, \n; } ^D # perl z.pl /tmp/ip.range =( print -l 192.168.1.1 192.168.1.4 ) 192.168.1.1:NO 192.168.1.4:YES # perl -le foreach (0..$ARGV[0]) { printf %d.%d.%d.%d\n, rand()%255, rand()%255, rand()%255, rand()%255 } 10240000 gt;| /tmp/ip.list # wc -l /tmp/ip.list 10240001 /tmp/ip.list # time perl z.pl /tmp/ip.range /tmp/ip.list gt;| /dev/null Real: 120.10s User: 105.21s System: 1.31s Percent: 88%% Cmd: perl z.pl /tmp/ip.range /tmp/ip.list gt;| /dev/null # /code/prebr /br /PS. Вкралась ошибка: неправильно сгенерил список ip адресов, надоbr /precode# perl -le foreach (0..$ARGV[0]) { printf %d.%d.%d.%d\n, int(rand(255)), int(rand(255)), int(rand(255)), int(rand(255)) } 10240000 gt;| /tmp/ip.list/code/prebr /Результат:br /precode# time perl z.pl /tmp/ip.range /tmp/ip.list gt;| /dev/null Real: 176.98s User: 153.23s System: 2.20s Percent: 87%% Cmd: perl z.pl /tmp/ip.range /tmp/ip.list gt;| /dev/null/code/prebr /br /PS2. Скорость слабо зависит от количества сетей:br /precode # for i in {1..300}; do a=$[ $RANDOM%255 ]; b=$[ $RANDOM%255 ]; c=$[ $RANDOM%254 ]; d=$[ $RANDOM%254 ]; print $a.$b.$c.$d,$a.$b.$[$c+1].$[$d+1]; done gt;| /tmp/ip.range2 # time perl z.pl /tmp/ip.range2 /tmp/ip.list gt;| /dev/null Real: 187.54s User: 173.13s System: 1.98s Percent: 93%% Cmd: perl z.pl /tmp/ip.range2 /tmp/ip.list gt;| /dev/null # /code/prebr /a name=cutid1-end/a
Категории: Друзья

Версия пакета в package.

Чт, 11/17/2011 - 08:59
Можно теперь писать так:br /precode package Package 1.23; ... print $VERSION, \n; ... 1; /code/prebr /Но версия в таком операторе не вычисляется, там надо писать именно число.br /Т.е. такое выражение даст ошибку:br /precode package Package qw$Revision: 1.23 $[1]; /code/pre
Категории: Друзья

разбор ini-файла

Чт, 10/20/2011 - 16:42
Простейший ini-файл:br /br /codepre # Comment Param1 = Value1 [Section1] Param2 = Value2 LongParam = Very \ Long \ Param [Section2] Param3 = Value3 /code/prebr /br /a name=cutid1/abr /codepre # perl -MData::Dumper -0777 -lne s#\#.*?\n##gm; s#\\\n\s+##gsm; my $sect = __DEFAULT__; while (m#(?:(?name\w+)\s*=\s*(?value.+?)\s+$|\[(?sect\w+)\])#gm) { $sect = $+{sect} || $sect; $hash{$sect}-gt;{$+{name}} = $+{value} if exists $+{name} } print Dumper \%hash /tmp/a.ini $VAR1 = { Section1 =gt; { LongParam =gt; Very Long Param }, Section2 =gt; { Param3 =gt; Value3 }, __DEFAULT__ =gt; { Param1 =gt; Value1 } }; # /pre/codebr /br /Или в виде функции:br /br /codepre sub ini ($) { local $_ = do { local $/; open F, $_[0] and f }; s#\#.*?\n##gm; s#\\\n\s+##gsm; my $sect = __DEFAULT__; my %hash; while (m#(?:(?name\w+)\s*=\s*(?value.+?)\s+$|\[(?sect\w+)\])#gm) { $sect = $+{sect} || $sect; $hash{$sect}-gt;{$+{name}} = $+{value} if exists $+{name} } return \%hash; } /pre/codebr /a name=cutid1-end/a
Категории: Друзья