open F, ">file.ext" or die "Не могу открыть файл $file.ext: $!";
@m=;
close F;
binmode устанавливает Бинарный режим.
read - читает данные из дескриптора файла, параметры:
read F, $scalar, $lenght, $pos;
В параметре $lenght указывается число байтов, которые необходимо прочитать из дескриптора F и записать их в скалярную переменную. Параметр $pos; указывает, с какой позиции от начала скаляра нужно размещать считанные байты.
pack - упаковка значений в бинарную структуру по шаблону. Параметры:
pack шаблон, список.
Шаблон - последовательность букв, которая задает порядок и тип значений:
@ - заполнить двоичными нулями до след. абс. позиции.
a - текстовая строка, заполняемая двоичными нулями.
С - однобайтовое целое без знака
, для любого числа повторений испошьзуется символ *.
print pack("C*", 68, 69, 70, 71);
DEFG
unpack возвращает структуру, упакованную функцией pack с шаблоном, заданным при упаковке pack, в нашем случае C*.
substr - подстрока тектстовой строки, переданная в качестве аргумента. Параметры:
substr $text, $pos, $lenght, $regex;
$text = передаваемый текст, $pos - смещение, подстрока начинается с символа, имеющего заданное смещение от начала строки
Сканирование поддиректорий
Иногда бывает необходимо заменить во всех файлах всех поддиректорий какое-либо слово или баннер. Можно воспользоваться программой, которая рекурсивно ходит по поддиректориям и просматривает в них все файлы. В принципе на основе этого скрипта возможно выводить дерево каталогов или наводить статистику по всем файлам, допустим столько-то html, столько-то txt. Или просто иногда поискать что-нибудь, используя аналог unix'овой команды find. Приведенный код позволяет просматривать все файлы в поддиректории и заменять в них код определенного баннера:
#!/usr/bin/perl
$dir="/usr/local/www/allsitecopy";
&scan($dir);
sub scan {
my $dir=$_[0];
my (@files,$filen,$ndir,$n,$mass,@dirs);
opendir D, $dir or warn "Cannot open $dir: $!" and next;
@dirs=grep {!(/^\./) && -d "$dir/$_"} readdir D;
rewinddir D;
@files=grep {!(/^\./) && /html/i && -f "$dir/$_"} readdir D;
closedir D;
for $n(0..$#dirs) {
$ndir=$dir."/".$dirs[$n];
&scan($ndir);
}
for $n(0..$#files) {
$filen=$dir."/".$files[$n];
print "$filen all ok!\n" if($filen=~m!\.html$!i);
if($filen=~m!\.html$!i){ local $/="\001";
open F, "<$filen"; $mass=<F>; close F;
open F, ">$filen";
$mass=~s%<!--begin banner1-->(.*?)<!--end banner1-->%%igsm;
print F $mass;
close F;
}
}
return 1;
}
можно немного модифицировать приведенный выше код:
#!/usr/bin/perl
my $dir="/usr/local/www/allsitecopy";
all_files($dir);
sub all_files{
my $cur_dir = shift;
chdir $cur_dir || warn "can't open dir $cur_dir\n";
foreach(<*>){
if (-f "$cur_dir/$_") { action("$cur_dir/$_"); }
if (-d "$cur_dir/$_") { all_files("$cur_dir/$_"); }
}
}
sub action{
...что то там сделать...
my $file = shift;
print "$file\n";
}
Это-же можно сделать и из командной строки:
find /usr/local/www/allsitecopy -name \*.html -print | xargs \
perl -p0i.bak -e 's/<\!--begin banner1-->(.*?)<\!--end
banner1-->//igs'
from Alex Farber