Программирование PC Perl: немного о языке Fri, March 29 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Perl: немного о языке Печать
Добавил(а) microsin   

Perl - скриптовый язык, активно используемый в shell-ах *nix систем и для www-приложений. Существуют интерпретаторы Perl, работающие под Windows.

Например, Perl активно используется в Cisco Works. Физически интерпретатор perl.exe находится в каталоге c:\Program Files\CSCOpx\bin\. Скрипты имеют расширение *.pl и находятся в самых разных каталогах. Например, скрипт бэкапа логов находится в файле c:\Program Files\CSCOpx\mcp\bin\backupSyslog.pl, и этот скрипт запускается планировщиком командой C:\ WINNT\ system32\ cmd.exe /c C:\ PROGRA~1\ CSCOpx\ bin\ perl C:\ PROGRA~1\ CSCOpx\ mcp\ bin\ backupSyslog.pl, при этом каталог запуска (Start in:) не задан (пустой).

1. Если в PATH прописан путь до perl.exe, то скрипты можно запускать из любого каталога простой командой

perl.exe имя_файла_скрипта.pl

Передача параметров в скрипт происходит через массив @ARGV, где @ARGV[0] - первый параметр, @ARGV[1] - второй и т. д.

2. Комментарии начинаются с символа # и продолжается до конца строки. Многострочные комментарии не предусмотрены.

3. Декларация переменной, присвоение ей значения, вывод строки:

print "Hello World\n";
$testvar = "this is test line\n";
print $testvar;

4. Выход из программы с помощью exit (переменная testvar не выведется):

print "Hello World\n";
$testvar = "this is test line\n";
exit;
print $testvar;

Выход из программы с помощью оператора die сообщение:

open SRCFILE, ' < ', $file or die "Cannot open file ".$file.": $!\n";

5. Вывод содержимого переменной вместе с текстом:

$logfile = "AAA";
print "$logfile\nBBB";

выведется:

AAA
BBB

6. Конкатенация ("склеивание") двух строк:

$str1="AAA";
$str2="BBB";
$str3 = "$str1"."$str2";
print $str3;
print "$str1"."$str2";
print $str1.$str2;

выведется:

AAABBBAAABBBAAABBB

7. Запуск из perl другой программы.

system "C:\\ARC\\RAR\\RAR.EXE a test.rar 
 \"c:\\Program Files\\CSCOpx\\log\\bkp\\sysLog-06.08.2007.log\"";
system "C:\\ARC\\RAR\\RAR.EXE", "a", "test.rar",
       "\"c:\\Program Files\\CSCOpx\\log\\bkp\\sysLog-06.08.2007.log\"";
print "exit from rar\n";
system "calc";
print "exit from calc\n";

Строка 'exit from calc' напечатается, когда программа calc.exe будет закрыта. Обратите внимание, что system может вызываться как с одним параметром, так и с несколькими - каждый параметр будет представлять из себя часть командной строки. При необходимости использовать слеш или двойные кавычки их надо экранировать символом слеша (\), это видно в примере. В случае использования system запуск программы происходит интерактивно - пользователь видит в консоли процесс работы rar и видит открытое GUI-окно калькулятора calc.exe. Другой пример, с использованием open:

$cmd = "C:\\ARC\\RAR\\RAR.EXE a test.rar
 \"c:\\Program Files\\CSCOpx\\log\\bkp\\sysLog-06.08.2007.log\"";
open(OUT, "cmd /c $cmd|");
close(OUT);
print "exit from rar\n";
$cmd = "calc";
open(OUT, "cmd /c $cmd|");
close(OUT);
print "exit from calc\n";

Отличие в работе здесь только в том, что на экране консоли не видно, что rar работает. По завершении архивирования выводится строчка 'exit from rar'. Это не относится к GUI-окну calc, оно появляется на экране, как и в предыдущем примере. После закрытия пользователем калькулятора в консоли появляется строка 'exit from calc'.

8. Получить список переменных окружения (распечатается содержимое переменной Path):

print $ENV{Path};

9. Получить список файлов в текущем каталоге, выполнив команду dir:

my $file_list1 = `dir`;  # в скалярном контексте
print $file_list1;

или

my @file_list2 = qx(dir); # в списочном контексте
print @file_list2;

или

print "$_ " foreach @file_list2

10. Получить список файлов и каталогов, расположенных по указанному пути командой glob:

@file_list1 = glob ("*.*");
print "$_\n" foreach @file_list1;

В параметре glob указывается маска для файлов.

11. Задержка в необходимое число секунд:

sleep 1; # в этом примере задержка 1 секунда

12. Функции и процедуры создаются с помощью ключевого слова sub. Пример простейшей процедуры (sub без параметров) и вызова её:

sub test
{
   print "Привет из подпрограммы!\n";
}
&test();

Символ & означает, что после него идёт вызов подпрограммы. Но можно даже обойтись вообще без него. А также можно обойтись и без скобок (Скобки нужны только в том случае, если передаваемые функции параметры могут вызвать неоднозначность трактования).

Пример функции с параметрами:

sub test
{
   print @_[0];
}
&test("Привет из функции!\n");

При вызове тела функции автоматически внутри функции становится доступен массив @_, элементы которого являются параметрами функции. Для возврата из подпрограмм и функций каких-нибудь значений существует оператор return:

sub test
{
   return "Это возвращаемое значение";
}
print &test();

Можно обходится и без оператора return - тогда Perl вернёт значение последнего оцененного выражения (но так лучше не делать, поскольку return дает наглядность и понятность текста). Ещё о передаче подпрограмме параметров. В Perl все переменные передаются по ссылке. Поэтому нет смысла передавать подпрограмме указатель на переменную.

13. Указатели и адреса переменных. Объявление указателя (оператор *):

*POINTER;

Взятие адреса переменной (оператор косая черта \):

*POINTER;
$x=0;
$POINTER = \$x;
print \$x."\n";
print $POINTER."\n";
print \$POINTER;

Выведется что-то типа:

SCALAR(0x9898b8)
SCALAR(0x9898b8)
SCALAR(0x9898a0)

14. Как вынести процедуры в отдельный файл - достаточно сохранить свою подпрограмму в файл (предположим "test.pl"), а в том файле, в котором стоит вызов подпрограммы написать require "test.pl".

15. Пример рекурсии. Рекурсивной называется подпрограмма, способная вызывать саму себя. Это дает возможность обработки древовидных структур, как то - дерево каталогов, ссылочная связь гипертекстовых документов и т.п.

$cnt=0;
sub recurs
{
   my $level = $_[0];
   $cnt++;
   print "$level\n";
   if($cnt < 10)
   {
      &recurs("$level\\$cnt");
   }
   $cnt--;
   print "$level\n";
}
  
&recurs(0);

В результате выведется:
0
0\1
0\1\2
0\1\2\3
0\1\2\3\4
0\1\2\3\4\5
0\1\2\3\4\5\6
0\1\2\3\4\5\6\7
0\1\2\3\4\5\6\7\8
0\1\2\3\4\5\6\7\8\9
0\1\2\3\4\5\6\7\8\9
0\1\2\3\4\5\6\7\8
0\1\2\3\4\5\6\7
0\1\2\3\4\5\6
0\1\2\3\4\5
0\1\2\3\4
0\1\2\3
0\1\2
0\1
0

16. Массивы. Имена массивов начинаются с символа @. Массивы декларируются автоматически вместе с присвоением значений элементам массива:

@file_dates[0] = 3;
@file_dates[1] = 10;
@file_dates[3] = 26;
print "$_\n" foreach @file_dates;

Этот код выведет

3
10

26

17. Циклы. Синтаксис for и while тот же самый, что и для C. Еще пример цикла с foreach (см. также пример 9):

@file_list1 = glob ($BKP_CATALOG1."file://*.log/");
foreach $i (@file_list1)
{
   print $i."\n";
}

Внимание, есть отличие и C! Для прерывания цикла используется не ключевое слово break, а ключевое слово last Кроме того, тело цикла должно быть обязательно заключено в скобки {} - одностроковое тело не исключение.

18. Операции сравнения. Интересно, что для сравнения чисел и строк используются разные операторы. Подробнее см. [1].

19. Длина строки вычисляется функцией length.

20. Удаление последнего символа строки производится функцией chop.

21. Подстрока от строки берется с помощью функции substr:

$substring = substr(Str, Offset[,Len]);

22. Операция поиск и замена в строке:

$m = "my string";
$m =~ s/my/our/; #переменная $m будет содержать строку "our string"

Операции поиска и замены могут использовать регулярные выражения.

23. Регулярные выражения. Подробнее см. [2].

Пример 1 - проверка соответствия переменной $fname соответствия паттерну sysLog-\d{2}\.\d{2}\.\d{4}\.log.

В переменной $fname ожидается содержимое наподобие sysLog-18.08.2007.log

if ($fname =~ /sysLog-\d{2}\.\d{2}\.\d{4}\.log/)
{
   print $fname."\n";
}

Если $fname соответствует, то выполняется print. Расшифровка паттерна:

- sysLog-
- 2 цифры
- символ точки
- 2 цифры
- символ точки
- 4 цифры
- символ точки
- log

Пример 2 - выделение из строки частей, соответствующих дате. Здесь с помощью скобок в регулярном выражении выделяются число, месяц и год. В переменной $fname ожидается содержимое наподобие sysLog-18.08.2007.log

if ($fname =~ /sysLog-(\d{2})\.(\d{2})\.(\d{4})\.log/)
{
   $days   = $1;
   $months = $2;
   $years  = $3;
   print $days.".".$months.".".$years."\n";
}

24. Операции с файлами.

ФункцияОписание
binmode Задает двоичный/текстовый режим ввода-вывода.
close Закрывает файл.
eof Проверяет, достигнут ли конец файла.
fileno Возвращает дескриптор открытого файла.
flock Блокирует/разблокирует файл.
getc Читает один символ из файла.
ioctl Операции управления вводом-выводом.
open Открывает заданный файл.
print Выводит в файл строку или список строк.
read Читает блок данных из файла.
readline Читает очередную запись из файла.
seek Изменяет текущую позицию в файле.
select Задает или возвращает указатель файла вывода по умолчанию.
sysopen Открывает заданный файл.
sysread Читает блок данных из файла.
sysseek Изменяет текущую позицию в файле.
syswrite Выводит блок данных в файл.
tell Возвращает текущую позицию в файле.
truncate Изменяет длину заданного файла.

Простой пример чтения текстового файла по строкам и вывода на экран:

open TXTFILE, '<', 'ipnatSC.rules' or die "Cannot open file: $!\n";
binmode TXTFILE?, ":crlf";        #смена режима работы с файлом от binary к text
while (!eof(TXTFILE))
{
   $line = readline TXTFILE;
   print $line;
}
close TXTFILE;

Пояснения к примеру. TXTFILE - описатель файла, на который ссылаются при обращении к нему. ' < ' означает открыть файл ipnatSC.rules только для чтения. Оператор die завершает скрипт в случае ошибки, и выводит сообщение об ошибке $!, предоставляемое системой. По умолчанию файл открывается в двоичном режиме, и чтобы перейти в текстовый, надо использовать оператор binmode (однако для работы оператора readline это необязательно). При записи в текстовом режиме символ конца абзаца 0A (hex) заменяется на последовательность 0D0A. Функция eof() возвращает true как только будет достигнут конец файла.

Еще простой пример построчного копирования одного файла в другой:

open SRCFILE, '<', $file or die "Can't open ".$file.": $!\n"; #открыть только на чтение
open DSTFILE, '>', $tmp or die "Can't open ".$tmp.": $!\n";   #открыть только на запись
while (!eof(SRCFILE))
{
  $line = readline SRCFILE;
  print DSTFILE $line;                                        #вывод в файл
}
close SRCFILE;
close DSTFILE;

25. Аналог функции Trim (удаление из начала и конца строки пробелов). Ключевое слово for здесь используется не для указания цикла, а для перевода контекста на строку $string.

sub trim 
{
   my($string)=@_;
   for ($string)
   {
      s/^\s+//; #обрезать в начале
      s/\s+$//; #обрезать в конце
   }
   return $string;
}

26. Оператор проверки условия if, else имеет такой же синтаксис, как у C, отличие только в том, то нельзя тело оператора, даже однострочного, оставлять без скобок {}.

[Ссылки]

1. Perl: выражения и операции.
2. Perl: регулярные выражения

 

Добавить комментарий


Защитный код
Обновить

Top of Page