|
На главную
Как получить файл по FTP
О1. Воспользоваться модулем Net::FTP
$ftp = Net::FTP->new("е.е.е.е", Debug => 0);
$ftp->login('anonymous','anonymous');
$ftp->cwd('/pub');
$ftp->get(test.pl,test2.pl,/pub/incoming);
$ftp->quit;
Получить сумму значений на основе файла, каждая строка которого число
О1.
open (F,"file") or die $!;
map { $a += $_; } ;
print $a;
О2.или короче:
open (F,"file") or die $!;
print (map { $a += $_; } )[-1];
by arto
Проверить email на валидность
О1.http://search.cpan.org/author/MAURICE/Email-Valid-0.15/Valid.pm
Использование нескольких локалей
Вопрос:
У меня есть слово в верхнем регистре мне его нужно перевести в нижний, и все бы
сводилось к простой задаче если бы не одно НО! слова могут быть как минимум на
четырех языках... То есть:
#!/usr/bin/perl -w
use strict;
use locale;
my $var = "TEST";
print lc($var);
---------------
test
О1. by Vlad
use strict;
use locale;
use POSIX qw(locale_h);
{
setlocale(LC_CTYPE,"ru_RU.ISO8859-5");
my $var = "ЛАЛА";
print lc($var),"\n";
}
{
setlocale(LC_CTYPE,"en_US.ISO8859-1");
my $var = "TEST";
print lc($var),"\n";
}
Разбор тегов в файле
Вопрос: Есть текст вида
<element>!</element>
<element>!</element>
<element>!</element>
<element>!</element>
<element>!</element>
<element>!</element>
<element>!</element>
и тп (порядка 20 метров). Нужно все это засунуть в массив.
Можно сделать вот так:
while ($data =~ s/<element>(.*?)</element>/) [
$arr = $1;
}
Но это сильно тормозит.
Можно использовать split (он как раз быстро работает):
@rrr = split(/<element>(.*?)</element>/,$data);
Но в этом случае в массив кидается все, что находится за пределеами element...
Как это лучше сделать?
О1. by Light_Elf
open FILE, "<$file";
push @data, (/<element>(.*?)</element>/)[0] while (<FILE>);
close FILE;
Работа со случайными и псевдослучайными числами
Вопрос:
есть четыре скаляра:
$a = 1;
$b = 2;
$c = 3;
$d = 4;
Как сделать так, чтобы при обращении к скрипту, perl каждый раз показывал
произвольный скаляр, ну например захожу я на test.pl а на экране горит 2, жму
"Refresh", горит 1, сново жму "Refresh" уже на экране 3 и т.д. Или не
произвольный скаляр, а заданную последовательность наприер: 4,1,3,2 а потом
сново с четырех и т.д. и т.п.
О1. by Arto
${qw(a b c d)[int rand(5)]}
О2. by LeXa_NalBat
${[qw(a b c d)]}[rand(4)]
Определение и условная передача размера файла
Вопрос:
Как можно определить существует ли файл /tmp/aaa.txt
и если существует передать переменной его размер, если нет -не прерывать
выполнение кода? Мне нужно чтобы код продолжал выполняться если файла нет.
например:
если файл есть - получаем его размер
если файла нет - print "Файла нет\n";
... # продолаем выполнять код
а в вышеприведенном примере, если файла нет то скрипт прерывает свою работу.
О1. by Vlad
use strict;
my $f_name = '/tmp/aaa.txt';
unless (-d $f_name) {
defined(my $f_size = (stat($f_name))[7]) or print "fila $f_name net";
print $f_size;
} else {
print "$f_name ne file";
}
О2. by Whirlwind
use strict;
my $f_name = 'c:\\test.pl';
print "$f_name ",(-f $f_name ? "file ".(-s $f_name)." bytes" :
"not ".(-e $f_name ? "a file" : "exists" ));
Выловить все ссылки из переменной
Вопрос: Мне нужно с помощью регулярных выражений выловить из
переменной все ссылки http://бла-бла-бла.бла
О1. by LeXa_NalBat
/http:\/\/\S+/g
Работа с датами в текстовой БД
Вопрос: Есть текстовая БД такого вида:
01/01/2004blablalalala...
02/01/2004blabla2lalala2...
29/01/2004blabla3lalala3...
30/01/2004blabla4lalala4...
и так далее.
Есть html форма где пользователь долежен ввести дату, например, искать от
01/01/2004 и до 30/01/2004.
Скрипт должен вывести результаты от 01/01/2004 и до 30/01/2004 одно или
несколько значений, которые идут за соотвующей датой.
Например, пользователь говорит, найти второе значение в БД от 01/01/2004 и до
30/01/2004 и скрипт должен вывести результат
01/01/2004 lalala
02/01/2004 lalala2
.....
29/01/2004 lalala3
30/01/2004 lalala4
О1. by Whirlwind
@a = qw(
01/01/2004blablalalala...
02/01/2004blabla2lalala2...
29/01/2004blabla3lalala3...
30/01/2004blabla4lalala4...
);
$beg_date = sd2nd("02/01/2004");
$end_date = sd2nd("29/01/2004");
foreach (@a){
next unless /^((\d{2})\/(\d{2})\/(\d{4}))(.*)/;
$text = $5;
$date = $1;
next if sd2nd($date) < $beg_date;
last if sd2nd($date) > $end_date;
print "$date - $text\n";
}
sub sd2nd{
my $s = shift;
return unless $s =~ s#^(\d+)/(\d+)/(\d+)#
sprintf("%.04i%.02i%.02i",$3,$2,$1)#e;
$s;
}
Как определить имя хоста
Вопрос: Есть IP. Надо определить имя этого хоста. Как это сделать просто и быстро?
О1. by biting
#!/usr/bin/perl
use Socket;
$ip="81.19.66.109";
@ip=split(/\./,$ip);
$host=gethostbyaddr(pack("C4",@ip), AF_INET);
print "$host\n";
Как узнать, установлен ли модуль
Вопрос: Можно ли как-нибудь узнать, установлен ли определенный модуль на сервере?
О1. by Whirlwind
print (eval "use 'module.pm'" ? "Ok" : $@);
Как заменить текст в файле
О1. by Whirlwind
open(F,"+<$file") or die "Cannot open $file $!\n";
binmode(F) or die "Cannot binmode $file $!\n";
@D=<F>;
seek(F,0,0);
foreach(@D){
s/шило/мыло/g;
print F;
}
truncate(F,tell(F));
close(F);
Экспорт функций
Вопрос: В пакете a.pm определена функция connect.
А в модуле imod.pl мне нужно эту функцию использовать.
Как это сделать?
О1. by Light_Elf
package my_package;
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(my_func);
sub my_func {1}
Разбить число на триплеты
Вариант perl
$_ = 100000000000000;
1 while s/(\d\d\d)(\d\d\d)(?!\d)/$1,$2/;
print
Вариант perl
$_ = 4294967296;
# $i=3; $i+=4 while s#(.{$i})$#,$1#;
$i=3; $i+=4 while s#(.{$i})$#($`?",":"").$1#e;
print
Определить есть ли соединение по хэндлеру сокета
Для определения факта соединения можно воспользоваться функцией
getpeername.
Вариант perl
use Socket;
...
if (getpeername(SOCK)){
print "Есть соединение - работаем дальше\n";
}else{
print "Нет соединения - удаляем сокет\n";
...
}
...
Определить дату начала и конца недели
Посмотрите на проблему с другой позиции: если брать за основу время с начала
эпохи (а именно так компьютер 'считает' время - количество секунд, прошедших с
начала эпохи), то вся задача сводится к манипуляциям над целочисленными
значениями. Нижеприведенный пример демонстрирует алгоритм определения даты
начала и конца текущей недели.
Вариант perl
#!/usr/bin/perl -w
use strict;
my $dofw = (localtime)[6];
my $time = time;
my $inday = 86400;
print scalar(localtime(week_start())),"\n";
print scalar(localtime(week_end())),"\n";
sub week_start{
return $time - $inday * $dofw;
}
sub week_end{
return $time + $inday * (6 - $dofw);
}
Примечание: используйте модуль timelocal для получения абсолютной
точности.
Получить имена подпрограмм модуля
Вариант perl
#!C:/perl/bin/perl -w
use strict;
print join("\n",&get_sub_list);
sub go{}
sub test1{}
package sublist;
sub main::get_sub_list{
no warnings;
my ($code,@fn);
foreach (keys(%main::)){
next unless /^[\w_]/;
push(@fn,$_) if eval("defined(*main::$_"."{CODE})");
}
use warnings;
@fn
}
Получить постоянную последовательность чисел
Зачастую возникает необходимость получить последовательность чисел на основе
единственного значения.
Использование rand и srand
Самый простой вариант это использовать оператор rand на пару с srand. Встроенная
функция srand выполняет инициализацию генератора случайных чисел.
Передавая функции srand конкретное значение мы настраиваем генератор случайных
чисел на заранее определенную последовательность. Убедится в этом нам
поможет элементарный пример
Вариант perl
#!/usr/bin/perl -w
use strict;
rnd(5);
rnd(6);
rnd(1);
rnd(5);
sub rnd{
my $v = shift;
srand $v;
for (my $i = 0; $i < 5; $i ++){
print rand($v),"\n";
}
print "---------\n";
}
После выполнения программы мы увидем, что первая сгенерированная
последовательность совпадает с последней.
Свой генератор
Для понимания принципа работы генератора можно рассмотреть следующий пример
Вариант perl
sub get_sequence{
my ($n,$c) = @_;
my @r;
push(@r,int($c * $n + $n / 3.14 + $c))
while ($c-- > 0);
return @r;
}
Как видно из кода процедуры, работа алгоритма базируется на элементарной
математике. В зависимости от специфики задачи можно изменить алгоритм
рассчета числа и получать более сложную последовательность. Проверим
работоспособность этой функции
Вариант perl
print join("\n",get_sequence(5,3)),"\n\n";
print join("\n",get_sequence(2,3)),"\n\n";
print join("\n",get_sequence(5,3)),"\n\n";
Получить случайное число
Для генерации случайного числа в служит оператор rand. Единственный
аргумент функции определяет границу последовательности, из которой будет
происходит выборка значений. Это значит, что передав в качестве аргумента
функции rand, например, число 10, мы получим дробное число, которое будет
находится в промежутке от нуля (включительно) до 9,9999... (включительно).
Само переданное значение не входит в последовательность, оно лишь указывает
границу этой последовательности.
Примеры
Получение случайного целочисленного значения от 0 до 99
Вариант perl
$e = int(rand(100));
Выбор случайного элемента массива
Вариант perl
$e = $array[ rand @array ];
Примечание для perl:
Если у вас Perl ниже 5.004 версии тогда вам необходимо самостоятельно вызывать
функцию srand с произвольным значением. Вызов функции srand выполняет
инициализацию генератора случайных чисел. В качестве аргумента можно передать
текущее время. В общем случае раскрутка генератора случайных чисел может
выглядеть так:
srand(time());
Для Perl версии 5.004 и выше нет необходимости вызывать функцию srand. Perl
самостоятельно выполняет инициализацию генератора случайных чисел при первом
вызове rand.
Сгенерировать случайную строку (пароль, идентификатор)
Классический вариант, взятый из Perl Cookbook (рецепт 2.7)
@cs = ("A".."Z","a".."z",0..9,qw/% ! @ $ ^ & * - _ = +/);
$pass = join("",@cs[map { rand @cs } (1..8) ]);
Массив @cs должен содержать все допустимые в строке символы. Второй оператор
генерирует 8 случайных индексов, определяющих конкретный символ.
Ниже приведен пример функции, генерирующей строку случайных символов, пределы
длины которой определяются двумя аргументами.
Вариант perl
#!C:/perl/bin/perl -w
use strict;
print gen(8,32);
sub gen{
my ($min,$max,$len,@cs) = @_;
$len = int(rand($max - $min + 1)) + $min;
@cs = ("A".."Z","a".."z",0..9,qw/% ! @ $ ^ & * - _ = +/);
join("",@cs[map { rand @cs } ($min..$len) ]);
}
Поменять местами ключи и значения хэш-массива
Вариант perl
Используйте функцию reverse. Так как между контекстами хэша и обычного массива
разница слишком абстрактна, reverse прекрасным образом проглатывает в качестве
аргумента хэш-массив. С другой строны, любой массив с четным количеством
элементов может быть легко преобразован в хэш массив. При этом, нечетные
элементы станут ключами, а четные значениями.
%a = reverse %a;
Наверх
|