A Perl Script Nyelv


1973

Ken Thompson megalkotja a grep parancsot, melyben az ed szövegszerkesztő parancsai és beépített reguláris kifejezései egy külső programban valódulnak meg, a Global REgular expression Print-ben.

1977

Alfred V. Aho, Peter J. Weinberger, és Brian W. Kernighan megalkotja az awk számítógépes nyelvet. Az awk a Perl elődjének tekinthető.

1987

Dec. 18-án Larry Wall felteszi a hálózatra a Perl 1.000-át, és azonnal több ezer önkéntes hozzálát teszteléséhez és fejlesztéséhez. Larry Wall egy fájlarhíváló és hibajelentő rendszert szeretett volna megíni awk-ban, de az kevésnek bizonyult a problémához. Lusta programozó révén azonnal írt egy megfelelőbb programzási nyelvet.

	NAME
perl | Practical Extraction and Report Language
(gyakorlati kivonatolás és jelentés nyelv)

SYNOPSIS
perl [options] filename args

LEÍRÁS
A Perl egy parancsértelmező nyelv, melyet arra optimalizál-
tak, hogy átfésüljön egy tetszőleges szövegállományt, azok-
ból információt szedjen össze, és ennek alapján egy jelen-
tést nyomtasson ki. Igen hasznos nyelv számos rendszer kar-
bantartó feladatra is. Fő előnye inkább a gyakorlati alkal-
mazhatósága (könnyű használni, hatékony, teljes), mintsem
mintsem a szépsége (tömör, elegáns). A szerző véleménye sze-
rint magába ötvözi a C, sed, awk és sh legjobb tulajdonsága-
it, így azok számára, akik járatosak e nyelvekben, nem okoz
nagy nehézséget használata. A kifejezések szintaxisa nagyon
hasonlít a C nyelvére. Amennyiben olyan problémánk van,
melyet általában a sed, awk, vagy sh scriptekkel oldanánk
meg, de meghaladja azok lehetőségeit, vagy azoknál gyorsab-
ban szeretnénk futtatni, de nem óhajtuk a programot C-ben
megírni, akkor a perl a helyes választás. Rendelkezésre áll-
nak fordítóprogramok is, melyek a már meglevő sed és awk
programjainkat átírják perl-be.


Mivel kicsit rendetlen a formátuma, szokás a Perl-t még Patologikusan Eklektikus Rendetlenség Listázónak is nevezni. A szerző ezt is hivatalosnak tekinti.

#!/usr/bin/perl -w
print join " ", reverse split ' ', "hacker, Perl another Just"

1988

Június 5-én kijön a Perl 2.000.

(Nov 3-án Robert Tappan Morris megfertőzi a hálózatot az első féreggel).

1989

Okt. 18-án megjelenik a Perl 3.000, és első ízben a GNU Nyilvános Licensz alapján

1990

Guido van Rossum (CWI, Amsterdam) megalkotja a Python nyelvet.

Convex beépíti a Perl-t a sztenderd operációs rendszerébe.


1991

Márc. 21-én megjelenik a Perl 4.000, mind a GNU Nyilvános Licensz mind az Artistic licensz alapján.

Megjelenik a Linux GNU Nyilvános Licensszel.

1992

Januárban megjelenik a Perl MacIntosh verziója, a MacPerl, 4.0.2.

Decemberben felvetődik egy, a TeX mintájára szerveződő (Comprehensive TeX Archive Network  -- CTAN) arhíváló rendszer létrehozásának gondolata: CPAN -- Comprehensive Perl Archive Network.

1994

Okt. 18-án megjelenik a Perl 5.000, teljesen újraírják a Perl-t.


1995

Rasmus Lerdorf megalkotja a Perl CGI szkriptet, mely egy HTML dokumentumban információt gyűjtött a látogatókról, és azt beleírta a HTML dokumentumba. 

Megalakul hivatalosan a CPAN.

1996

Doug MacEachern megalkotja a mod_perl-t, mely beépíti a perl értelmezőt az Apache web kiszolgálóba.


1997

Kijön a Perl 6.

A Perl megjelenik Windows platformon is (ASP, OpenPerl)



2001

Open Cola 1.0 is the first open source consumer product and sports the following Perl code on the can: (24 April)


#!/usr/bin/perl
open CAN, "excitedly";
join ($can, $mouth);
while ($colaRemaining > 0)
{if ($reallyThirsty) {$chug;} else {$sip};}
dumpIN_RECYCLING_BOX;IN_RECYCLING_BOX;


Egyéb Linkek



Támogatott Operációs rendszerek


Perl főbb tulajdonságai


Perl és a Web


A Perl célja

A Perlt programozóknak tervezték, általános feladatokhoz, melyek túl nehezek vagy túl hordozhatóságérzékenyek a shell számára, és túl bonyolult azokat C-ben vagy más UNIX ragasztónyelven kódolni.

A Perl működése

A Perl a futtatandó programot először teljes egészében beolvassa és értelmezi, majd ha azt hibátlannak találta, akkor kezd neki a futtatásnak. Ezáltal előfeldolgozza a scriptet, és jelentősen gyorsítja a futását egy egyszerű értelmező scripthez képest. (Természetesen terjedelmes, rövid ideig futó program esetén ez pont fordítva van, az értelmezés sokkal hosszabb ideig tarthat, mint a program futása).

A Perl program alapszerkezete

#!/usr/bin/perl -w


Hello world

#!/usr/bin/perl
print "Hello world!\n";
# Használható a C mintájára a zárójeles argumentumátadás is.
print ("Hello world!\n");
# Használható a C mintájára a formázó karakterek is.
printf("%20s\n","Hello world");

Változók

$szam1 = 0377;
$szam1 = -0xff;
print "szam1=$szam1, szam2=$szam2\n";

eredménye
szam1=255, szam2=-255


Vezérlési szerkezetek


Input/Output


Szabályos Kifejezések

A perl igazi erőssége a szabályos kifejezések kezelése
if (/regex/) { ... }            # ha a $_ egyezik a regex-el, akkor ...
a /regex/ valójában az m/regex/ (match) rövidítése. Ha egy másik változón akarjuk megnézni az egyezést, akkor a
if ($a =~ /regex/) { ... } 
Hasonlóképpen, a szokásos módon elvégezhetőek a helyettesítések is
s/ab*c/def/;                  # a $_-ban az ab*c reguláris kifejezést helyettesíti def-el.
$a =~ s/ab*c/def/; # ugyanez az $a változóra

Kiterjesztett reguláris kifejezés

Példa: az egrep parancs:


A kiterjesztett reguláris kifejezés tartalmazza a reguláris kifejezéseket , és
extrák:
függetlenek a locale beállításoktól és az ASCII kódtáblától.

A szögletes zárójelek az osztályelnevezés részei így a keresésben duplán jelenik meg a szögletes zárójel:
/[[:digit:]]/                           # van benne számjegy
/[][:digit:]$&]/                   # van benne ] vagy számjegy vagy $ vagy &


\w   : [[:alnum:]]
\W : [^[:alnum:]]
\b   : \< vagy \> szóhatároló pozíció
\B  :  nem szóhatár



megkeresi, hogy hol fordul elõ az ajto vagy ablak szó magában.


(ablak)|(ajto){2,}

kifejezés az ablak legalább egyszeri, míg az ajto legalább kétszeri elõfordulását írja elõ. Az
(ajto)(ablak)|(ajto.*){2,}
viszont azt követeli meg, hogy egy sorban az ajto-t kövesse valahol az ablak VAGY az ajto ketszer szerepeljen. A | az elõtte levõ teljes kifejezést (reguláris kifejezések összefûzése) kapcsolja össze a mögötte álló reguláris kifejezéssel.


(ajto).*((ablak)|(ajto.*){2,})
az ajto után szerepeljen az ablak, vagy két ajto string.

((ajto)|(ablak)).*\1
az ajto vagy az ablak legalább kétszeri elõfordulását írja elõ.


?  +  *  .  { }  |  (  )  ^  $   \

karaktereket keressük, akkor le kell õket védeni a \ jellel. Míg egyszerû reguláris kifejezésben a
\(ablak\)
kifejezés az ablak stringet keresi, és azt eltárolja, ugyanez kiterjesztett reguláris kifejezésként a zárójelekkel körbevett ablak stringet keresi.


Alapesetben a tartományok és karaktertípusok kiértékelése az ASCII szekvencia alapján történik (ez a C locale). Ha az

További bővítések

perl, java, python, tcl ...
ld. http://www.tropicsoft.com/Components/RegularExpression/SyntaxBcb3.htm

perl


\d
[0-9]
\D
[^0-9]
\w
[a-zA-Z0-9_]
\W
[^a-zA-Z0-9_]
\s
[ \r\t\n\f]
\S
[^ \r\t\n\f]


Zárójel (csoportosítás)
( )  (?: )
Sokszorozók
?  +  *  {m,n}   ??   +?   *?  {m,n}?
referenciapont
^   $   \b   \B  \A  \Z   (?= )   (?<= )  (?! )   (?<! )
váltakozás
|


<B>ajtó</B> és <B>ablak</B>  szövegre a
/<B>.*</B>/      az ajtó</B> és <B>ablak -ra illeszkedik
/<B>.*?</B>/ az ajtó</B> -ra illeszkedik ugyanaz, mint /<B>((?!</?B>).)*</B>/
$pat = shift;
while (<>) {
print if /$pat/o;
}

$string = "Placido P. Octopus";
$regex = "P.";
$string =~ s/\Q$regex/Polyp/;
Ezek regex-en belül is ki-be kapcsolhatók:
<B>(?i:nagyon)</B>               # a nagyon állhat kis és nagy betúkből is.

Példa:

1. helyettesítsük az összes Jeffs kifejezést Jeff's -re

s/\bJeffs\b/Jeff's/g;                            # a triviális megoldás
s/\b(Jeff)(s)\b/$1'$2/g;                     # ugyanez csoportokkal
s/\bJeff(?=s\b)/Jeff'/g;                      # elővizsgálattal
s/(?<=\bJeff)(?=s\b)/'/g;                  # elő- és utóvizsgálattal
s/(?=s\b)(?<=\bJeff)/'/g;                  # ugyanaz, mint az előző

2. Csoportosítsuk egy egész szám számjegyeit hármas csoportokba
while ( s/(\d)((\d\d\d)+\b)/$1,$2/g) {}

3. szűrjük ki az ismétlődő szavakat egy HTML szövegben (lehet közben <parancs>, </parancs> alakú kifejezés is!)

$/ = ".\n";          # a beolvasásnál a . vagy az újsor a rekordhatár
while (<>) {
next if !s/\b([a-z]+)((?:\s|<[^>]+>)+)(\1\b)/\e[7m$1\e[m$2\e[7m$3\e[m/ig;
s/^(?:[^\e]*\n)+//mg; # A jelöletlen sorok eltávolítása
s/^/$ARGV: /mg; # Az állománynév beszúrása a sorok elejére
print;
}

A tr parancs


Függvények

$ertek="eredeti";
kiir();
kiir_svindli();
kiir_my();
kiir();

sub kiir_svindli {
local ($ertek) = "átmeneti"; # megváltoztatja az innen induló hívásokra is
kiir();
}

sub kiir_my {
my $ertek = "saját"; # csak a rutinon belül érvényes, a hívásokra már nem
kiir();
}

sub kiir {
print "Az aktuális érték $ertek\n";
}

eredménye:
Az aktuális érték eredeti
Az aktuális érték átmeneti
Az aktuális érték eredeti
Az aktuális érték eredeti
sub rutin() {
   arg1 = shift;
   arg2 = shift;
 
   ...
   return ($status,$szam,@lista);
}
....
($status,$n,@a) = rutin($a,$b,$c);   # meghívja a rutint $a,$b,$c argumentumokkal
($status,$n,@a) = &rutin;                   # meghívja a rutint a @_ argumentumokkal

$fuggveny="rutin";
($status,$n,@a) = &$fuggveny($a,$b);  # indirekt hívás név szerint

$fuggveny=\&rutin;
($status,$n,@a) = &$fuggveny($a,$b);  # indirekt hívás referencia szerint

sub rutin($$;$)  {  # két kötelező skalár és egy opcionális skalhívr argumentum
     ...
}

sub rutin1(@;@) {                             # egy kötelező és egy opcionális lista argumentum (nincs értelme)
  @ta = @_;
  print "a=@ta\n";
}

sub rutin2($;$) {                                  # egy kötelező és egy opcionális skalár (lista referencia) argumentum
  $pta = shift;
  @ta = @$pta;
  $ptb = shift;
  @tb = @$ptb;
  print "a=@ta\n";
  if(defined(@tb)) {print "b=@tb\n";}
}

@a=(1,2,3);
@b=(4,5,6);

rutin1(@a,@b);                                     # az (@a,@b) listával hívja meg
rutin2(\@a,\@b);                                  # referncián át adja át az a és b tömböket
rutin2(\@b);





Beállított változók

perldoc perlvar



Példák

while (<INP>) {
chomp;
s/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
print "$_\n";
}

vagy

perl -ne 's/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg; print $_' file1 file2 ...
while (<INP>) {
chomp;
s/([\x80-\xFF])/chr(0xC0|ord($1)>>6).chr(0x80|ord($1)&0x3F)/eg;
print "$_\n";
}
sub preserve_case($$) {
my ($old, $new) = @_;
my $mask = uc $old ^ $old; # a nagybetűs kifejezést bitenként kizáró VAGYolja az eredeti kifejezéssel

uc $new | $mask . # az előző maszkot VAGYolja az új kifejezéssel
substr($mask, -1) x (length($new) - length($old)) # a mask utolsó karaktere szerint alkalmazza tovább a kis/nagybetűt
}

$a = "this is a TEsT case";
$a =~ s/(test)/preserve_case($1, "success")/egi;
print "$a\n";

eredménye:
this is a SUcCESS case
$url =~ s/([^a-zA-Z0-9])/sprintf('%%%02x',ord($1))/ge;
print "$i: $_" if /^\# START/ ... /^\# END/;   # kinyomtat mindent a sor eleji #START és #END sorok között.

#!/usr/bin/perl

while (<>) {
print "header: $_" if 1 ... /^$/; # az első sor és első üres sor közötti rész
print "body: $_" if /^$/ ... eof(); # az első üres sor és állomány vége közötti rész
}

use LWP::Simple;

$url="http://elmfiz.elte.hu/fizinf/OpRendszerek/Perl.html";
$content = get $url; # a teljes HTML tartalmat betölti a content skaláris változóba

vagy

use IO::Socket;
unless (@ARGV > 1) {die "használat: $0 távoli_gépnév dokumentum ...";}
$host = shift(@ARGV);

foreach $document (@ARGV) {
$tavoli = IO::Socket::INET->new( Proto => "tcp",
PeerAddr => $host,
PeerPort => "http(80)",
);
unless ($tavoli) {die "nem tudtam csatlakozni a http démonhoz a $host gépen!";}
$tavoli->autoflush(1);
print $tavoli "GET $document HTTP/1.0\n\n";
while (<$tavoli>) {print}
close $tavoli;
}

vagy még általánosabban, interaktív párbeszéd a túloldali géppel:

use strict;
use IO::Socket;

my ($host, $port, $child, $handle, $sor);
unless (@ARGV == 2) {die "használat: $0 távoli_gépnév port ...";}
($host,$port)=@ARGV;

# tcp kapcsolat létrehozása
$handle = IO::Socket::INET->new( Proto => "tcp",
PeerAddr => $host,
PeerPort => $port,
)
or die "nem tudtam csatlakozni a $port portra a $host gépen: $!";
$handle->autoflush(1); # bufferelés kikerülése

print STDERR "[Csatlakozás a $host:$port-ra sikeres]\n";

# A program elágaztatása szülő és gyermek eljárásra:
die "nem sikerült a fork: $!" unless defined($child = fork());

# A szülő kapja a gyermek eljárás azonosítóját, a gyermek 0-t kap
if ($child) {
while (defined($sor = <$handle>)) {
print STDOUT $sor;
}
kill("TERM", $child); # SIGTERM küldése a gyermeknek
} else { # gyermek eljárás
while (defined($sor = <STDIN>)) {
print $handle $sor;
}
}

use locale;
$ENV{"LC_ALL"}="hu_HU";