Saturday, November 29th, 2008
Быстрый способ переименовать все изображения в папке 01 с чтототам.jpg в 01.jpg
#!/usr/bin/perl
my $i=1;
foreach (glob "01/*.jpg") {
if($_ =~ m#01/(.*?)(\.jpg)#i){
rename($_,"01/".$i.".jpg");
}
$i++;
}
Быстрый способ переименовать все изображения в папке 01 с чтототам.jpg в 01.jpg
#!/usr/bin/perl
my $i=1;
foreach (glob "01/*.jpg") {
if($_ =~ m#01/(.*?)(\.jpg)#i){
rename($_,"01/".$i.".jpg");
}
$i++;
}
system ("open /Users/myuser/Desktop/sendit.app");
Как известно, а если нет то огорчит, шестая версия php больше не будет поддерживать такой синтаксис как <? или <?=. И если в пятерке этот можно было поправить в php.ini файле и разрешить работу старых объявлений, теперь это будет не возможно. Что же делать? Горевать? Нет, использовать этот небольной код
find * -type f -exec perl -i -wpe 's/<\?[^(=|php)]/<\?php /g;
s/<\?=/<\?php echo /g;' {} \;
Итак, чем он занимается.
find * -type f - находим все файлы
-exec perl -i -wpе - натравливаем на них perl с его регуляркой
s/<\?[^(=|php)]/<\?php /g; - первая проверка, найти все после которых не идет равно или слово php, вдруг кто то использовал и новый и старые дескрипторы, и заменить его на <?php
s/<\?=/<\?php echo /g;’ - вторая проверка ловит старые коды <?= и меняет их на <\?php echo
в результате код
<? phpinfo(); ?> <?=$e?> <?php $e++; ?>
выглядит так
<?php phpinfo(); ?> <?php echo $e?> <?php $e++; ?>
PS: Вставляя в командную строку не забудьте соединить обе строки.
PS2: И сделать бакап
Вчера нарвался на довольно неприятную особенность работы с MySql у perl.
$sth1 = $dbh->prepare($sql);
$sth1->execute;
$sth3->bind_columns(\$id);
while($sth2->fetch){
...
$sth2 = $dbh->prepare($sql2);
$sth2->execute;
$sth2->bind_columns(\$big, \$autor);
$sth2->fetch;
}
Первый запрос, первый раз вернул “1″, которое подставилось в $sql2 и тогда второй запрос вернул “5″, “Мет”, но когда запрос пошел второй раз и значений равных условию не оказалось, то как думаете чему по прежнему равнялись переменные $big и $autor? по прежнему “5″, “Мет”.
Получается DBI не обнуляет переменные которым присваивает значения в случае нулевого возврата от SQL. Это надо делать самому, в ручную.
У wikipedia есть лозунг - “все есть статья”. Чем больше работаешь с perl, тем больше понимаешь, что неофициальный лозунг языка может звучать “все есть регулярное выражение”. Вот пример как подсчитать количество найденных вхождений в выражение. Скажем сколько букв “о” в традиционном “hello world”
#!/usr/bin/perl $text = 'hello world'; $text =~ s/[^o]//igs; print length($text)."\n"; # 2
Зацените красоту кода.
В системе MAC OS X заложен инструмент osascript позволяющий выполнять AppleScript через консоль. Это удобно, если скажем заходить на него через удаленный ssh или использовать в программах.
Вот простенький AppleScript
tell application "Finder" activate make new Finder window end tell
Он активирует Finder и открывает новое окно. Теперь запустим его через консоль.
osascript -e 'tell application "Finder"' -e "activate" -e 'make new Finder window' -e 'end tell'
Так как AppleScript требователен к переносам строк, а не использует индикатор окончания строки в виде точки с запятой как в Perl, то каждая новая строчка должна начинаться с атрибута -е.
Но можно рассширить возможности, запуская команды из программы написанной под консоль, например на Perl
#!/usr/bin/perl system "osascript -e 'tell application \"Finder\"' -e \"activate\" -e 'make new Finder window' -e 'end tell' ";
Уделите особое внимание кавычкам и как они экранируются. Можно так же передавать переменные
#!/usr/bin/perl $message = "hello"; system "osascript -e 'say \"$message\"'";
А теперь тоже самое для тех кто пишет под шелл
#!/bin/sh osascript -e 'tell application "Finder"' -e "activate" -e 'make new Finder window' -e 'end tell';
PS: все команды приведенные здесь должны быть в одну строчку
Как то прочел, что знаменитый Ларри Уолл (Larry Wall), создатель perl всегда отдавал предпочтение функциям которые хоть и не выглядели читабельными но были короткими. Странно, учитывая то, что он был лингвистом и должен был любить красоту слова. Тем не менее, лаконичность языка perl достаточно известна. Вот небольшой пример регулярных выражений где можно подсократить.
#!/usr/bin/perl
$a= 'Larry Wall';
if($a =~ m/(larry)\s(.*)/i){
print $2;
}
# Wall
Регулярное выражение не только проверяет наличие в тексте слова ‘larry’, но и присваивает совпадения переменным $1 и $2
Еще одна неприятность, это не возможность добавлять сразу и новый тег и текст внутри него как в DOMDocument
Вот для примера реализация на php
$tempA=$dom->createElement('a', 'mymans.org');
а вот perl
my $a = $doc->createElement('a');
my $text = $doc->createTextNode('mymans.org');
$a->setAttribute('href', 'http://mymans.org');
$a->appendChild($text);
хорошо хоть добавление аттрибутов работает по обычному
$a->setAttribute('href', 'http://mymans.org');
Впереди грядет Perl6 в котором многое уделено работой с XSLT поэтому пред этим надо по быстрому разобраться с XML на перле. Есть несколько молулей для работы с XML, но наиболее близким по синтаксису к DOMDocument в PHP мне показался модуль XML::DOM.
Для начала, пришлось устанавливать его из портов под FreeBSD. Под рутом итрпавился в путь
cd /usr/ports/textproc/p5-XML-DOM
и там запустил make install
После установки для теста создал простейший документ
#!/usr/bin/perl
use XML::DOM;
my $doc = XML::DOM::Document->new;
my $xml_pi = $doc->createXMLDecl ('1.0');
my $root = $doc->createElement('html');
my $body = $doc->createElement('body');
$root->appendChild($body);
print $xml_pi->toString;
print $root->toString;
Сохранив файл и дав ему права на запуск получаю вот такой вывод
<?xml version="1.0"?><html><body/></html>
Из не совсем привычных вещей это два принта для вывода одного файла. Но, как говориться, кудаж без этого в perl, было бы странно, будь оно не так. Не стоит переживать, в этом случае print служит вызовом метода класса,
print $xml_pi->toString; - вызывает метод который добавляет версию к документу
print $root->toString; - выводит сам документ
Как справедливо заметил djem способ чтения файлов по маске через `ls` экзотичен, а сам perl имеет встроенный механизм glob, и вот как это работает.
#!/usr/bin/perl
foreach (glob "*.webloc") {
print $_,"\n";
}