[[oktatas:programozás:perl|< Perl]]
====== A Perl nyelv ======
* **Szerző:** Sallai András
* Copyright (c) Sallai András, 2011, 2012, 2015, 2016, 2017, 2018, 2019
* Licenc: GNU Free Documentation License 1.3
* Web: http://szit.hu
===== A Perl nyelvről =====
A Perl nyelvet **Larry Wall 1987. december 18**-án tetté közzé. Rendszergazdai eszköznek készült.
Ha Perl nyelvről beszélünk akkor, rugalmasság, engedékenység, alakíthatóság tulajdonságok a megfelelő jelzők.
Maga Perl szó eredetéről több változat is ismert. Egyik változat szerint Larry Wall egy olyan nevet keresett a nyelv számra, ami kifejezi annak nagyságát, szépségét. Larry gondolkozott a felesége Gloria nevén is, végül Pearl mellett döntött, amely magyarul **gyöngyöt** jelent. A nyelv terjesztése előtt, azonban észrevette, hogy a Pearl szót már mások használják, ezért változtatott kicsit, kivette az "a" betűt a szóból, így lett Perl.
Más elgondolások szerint a Perl a **Practical Extracting and Reporting Language** szavakból alkotott betűszó, amely magyarul praktikus szerkesztő és jelentéskészítő nyelv. Egyesek szerint Pathologically Eclectic and Rubbis Lister, vagyis betegesen túldíszített szemét listázó.
A Perl nyelv mindenesetre fejlett mintaillesztő szerkezeteket támogat. A Perl nyelv ezen tulajdonság annyira népszerű lett, hogy ma már más nyelvek a POSIX mintaillesztés mellett a Perl nyelv szintaxisát építik a nyelveikbe.
===== Helló Világ nevű program =====
#!/usr/bin/perl
print("Helló Világ");
Az első sor csak unix alapú rendszeren, mint a Linux szükséges.
Az operációs rendszer ebből tudja milyen értelmezőnek kell
értelmezni a parancsokat. Windowson ez a kiterjesztésből
derül ki, ezért Windowson felesleges az első sor.
Unix alapú rendszeren futtathatóvá kell tenni a perl állományt.
Tegyük futtathatóvá:
chmod u+x hello.pl
Majd így futtatjuk:
./hello.pl
===== Megjegyzés =====
A perl nyelvben egy soros megjegyzéseket "#" karakterrel tehetünk,
az alábbi mintának megfelelően:
# egy soros megjegyzés
===== Kivitel =====
print "szilva";
print STDOUT "szilva";
print 'szilva';
print 45;
print 28, 83, 34, 56;
print 4, ' ';
print("alma");
print STDOUT ("körte");
print('szilva');
print(48);
print(34, 38, 92, 33);
Kifejezés kiértékelése:
print(42 * 2);
print 42 * 2;
print sqrt(9);
Ha a programozó a képernyőre ír, akkor azt két módon teheti meg.
Írhat az alapértelmezett kimenetre, és a hibakimenetre.
Mindkettő a monitorra ír. Akkor mi értelme van? A Perl scriptet
futtató rendszergazda azonban a kettőt szét tudja választani.
Írjuk meg például a következő perl scriptet:
#!/usr/bin/perl
print "Normál üzenet";
A script az alapértelmezett kimenetre ír. Futtassuk és tároljuk el
a kimenetet:
./csinal.pl > log.txt
A következő scriptben írjunk a hibakimenetre:
#!/usr/bin/perl
select(STDERR);
print "Hiba üzenet";
Futtassuk újra a scriptet és tároljuk el a kimenetet:
./csinal.pl > log.txt
Az állomány üres lesz, 0 méretű. A ">" jel csak az alapértelmezett
kimenetet irányítja a fájlba. A hibakimenetnek 2-es az azonosító száma.
Ezt kell megadnunk. Futtassuk újra a scriptet:
./csinal.pl 2> log.txt
Az üzenet, most az állományba íródik.
Megfordítva. Ha az első scriptet futtatom, "2>" karakterpárossal,
akkor a kimeneti állomány üres lesz.
A print utasítás a kimenetet először a ideiglenes tárolóba írja, így
lehet nem nem jelenik meg azonnal a monitoron. Ez segíthet ha a kiíratás
előtt a következő utasítást használjuk:
$|++;
print "Alapértelmezett kimenet\n";
A hibakimenet azonnali képernyőre küldése:
$|++;
select(STDERR);
print "Hibakimenet\n";
De használhatjuk a syswrite() függvényt is.
===== Adatok és változók =====
A Perl nyelven alapvetően kétféle változó van. A skaláris és a lista.
A skaláris adatszerkezet fogalom a Perl nyelvben azokat az adatszerkezeteket jelenti,
amelyek csak egyetlen elemből állnak. A számok és a karaktersorozatok egyaránt skaláris adatok.
Minden skaláris változót egy "$" karakterrel kell bevezetni. A változókat nem szükséges előkészíteni a változó típusának megadásával. Egyszerűen csak használatba vesszük.
Mint arról feljebb szó volt, a számok és a karaktersorozatok skaláris adatok. Létezik
a skaláris adatoknak egy harmadik fajtája is. Ezek a hivatkozások, vagy idegen szóval
referenciák.
A számok lehetnek egészek, valósak, hexadecimálisak, oktálisak, ezredes tagolással vagy tudományos alakban megadottak:
* 45
* 45.287
* .05
* 5.
* 5_347_343
* 5E2
* 5E-2
* 0xf1ab
* 024
$a = 3;
$b = 4;
A változók értékeket az "=" karakter operátorral kaphatnak.
Karaktersorozat állandók megadása:
$s = "alma";
vagy:
$s = 'alma';
Karaktersorozatot megadhatok idézőjelek és felső veszők között is.
A számok automatikusan átalakulnak karaktersorozattá, vagy vissza,
a környezettől függően. Kivételt jelentenek a hexadecimális és oktális
számok átalakítása.
Azt is megtehetjük, hogy egy szöveges változót és egy szám változó
megpróbálunk összeadni:
#!/usr/bin/env perl
$a = "szilva";
print $a + 2;
Az eredmény 2 lesz.
Ha bekapcsoljuk a figyelmeztetéseket a -w kapcsolóval,
akkor azonban meg is kapjuk a figyelmeztetést:
#!/usr/bin/env perl -w
$a = "szilva";
print $a + 2;
Eredmény:
Argument "szilva" isn't numeric in addition (+) at prog01.pl line 4.
2
Nem csak skaláris, de minden változóra igaz a Perl nyelvben:
* betűkkel kezdődhet
* aláhúzásjellel kezdődhet
* az első karakter után a következők lehetnek: betű, szám, aláhúzás
* maximum 255 karakter
* kis és nagybetűk kölönböznek
===== Escape szekvenciák =====
Ha szeretnék egy karakter arra használni, hogy a képernyőre íródjon
csak ennyit teszek:
print "n";
Esetleg három karakter:
print "anb";
Néhány karakternek azonban lehet speciális értelmezése is.
A speciális értelmezést a "\" karakterrel határozzuk meg.
Például:
print "\n";
Három karakterrel:
print "a\nb";
Az "a" betűt szimplán szeretnénk kiíratni, a "n" karakternek
viszont speciális értelmezését szeretnénk. Ha programot
végrehajtjuk, egy sortörést tapasztalunk az "a" karakter után.
Ilyen speciális jelentése van például a "t" karakternek is:
print "a\tb";
Végrehajtás után egy tabulátorhelyet kapunk az "a" és a "b" karakter
között.
Az olyan karaktereket, amelyeknek speciális értelmezése is van,
escape szekvenciáknak nevezzük. A következő táblázat bemutatja az
escape szekvenciákat.
^ Szekvencie ^ Hatása ^
| \n | sortörés |
| \t | tabulátor |
| \r | kocsi vissza |
| \f | lapdobás |
| \b | törlés vissza (backspace) |
| \e | kilépés |
| \a | csnegőhang |
| \0nn | oktális szám megadása |
| \xnn | hexadecimális szám megadása |
| \cC | vezérlő karakterek (a C bármi lehet; \cC például: Ctrl+C) |
| \Q | a mintákat nem kell egyeztetni, csak a szabályos kifejezéseket |
| \E | a \Q, az \L és az \U hatásának vége |
| \L | a következő betűk kisbetűsek |
| \l | a következő betű kisbetűsek |
| \U | a következő betűk nagybetűsek |
| \u | a következő betű nagybetűsek |
===== Operátorok =====
^ Aritmetikai operátorok ^^
| + | összeadás |
| - | kivonás, tagadás |
| * | szorzás |
| / | osztás lebegőpontosan |
| % | maradék |
| ** | hatványozás |
^ Összehasonlító operátorok számokhoz ^^
| == | egyenlő |
| != | nem egyenlő |
| > | nagyobb |
| < | kisebb |
| >= | nagyobb vagy egyenlő |
| <= | kisebb vagy egyenlő |
^ Összehasonlító operátorok karakterláncokhoz ^^
| eq | egyenlő |
| ne | nem egyenlő |
| gt | nagyobb |
| lt | kisebb |
| ge | nagyobb vagy egyenlő |
| le | kisebb vagy egyenlő |
^ Logikai operátorok ^^^
^ Perl stílus ^ C stílus ^ Leírás ^
| and | && | ÉS művelet |
| or | || | VAGY művelet |
| not | ! | tagadás |
^ Értékadó operátorok ^^^
^ Operátor ^ Minta ^ Jelentés ^
| += | $a += 2 | $a = $a + 2 |
| -= | $a -= 2 | $a = $a - 2 |
| *= | $a *= 2 | $a = $a * 2 |
| /= | $a /= 2 | $a = $a / 2 |
| %= | $a %= 2 | $a = $a % 2 |
| **= | $a **= 2 | $a = $a ** 2 |
^ Növelő és csökkentő operátorok ^^
| ++ | növelés |
| -- | csökkentés |
^ Precedencia ^^^
^ operátor ^ csoportosíthatóság ^ jelentés ^
| -> | balra | hivatkozás feloldása |
| ++ -- | nincs | |
| ** | jobbra | hatvány |
| ! ~ \ + - | jobbra | logikai nem, bitenkénti nem, referencia, egytényezős + és - |
| =~ !~ | balra | mintaillesztés |
| * / % x | balra | szorzás, osztás, maradék, karakterlánc ismétlés |
| + - . | balra | összeadás, kivonás, karakterlánc összefűzés |
| << >> | balra | bitenkénti eltolás |
| egytényezős operátorok | nincs | |
| < > <= >= lt gt le ge | nincs | összehasonlítás |
| == != <=> eq ne cmp | nincs | összehasonlítás |
| & | balra | bitenkénti ÉS |
| | ^ | balra | bitenkénti vagy, bitenkénti kizáró vagy |
| && | balra | ÉS |
| || | balra | VAGY |
| .. | nincs | tartomány megadása |
| ? : | jobbra | feltételes művelet |
| = += -= *= /= %= **= | jobbra | értékadás |
| , => | balra | vesző, lista eleme |
| listaoperátorok | nincs | |
| not | jobbra | tagadás |
| and | balra | ÉS |
| or xor | balra | VAGY, kizáró VAGY |
===== Formázott kivitel =====
Az alábbi program kiírja a változó tartalmát a képernyőre:
$a = 3;
printf("%d\n", $a);
Persze így nem különbözik a szimpla print() utasítás hatásától.
A printf() utasításnak két paramétere van. Az első a formátum
sztring. A második egy változó. A formátum sztring határozza meg,
hogy a változót milyen formában írjuk ki, mi legyen előtte, mi
legyen utána írva. A példában a változó kiíratása után egy
sortörésjel következik.
Ha ez egy pénzösszeg, akkor például írhatjuk ezt:
$a = 3;
printf("%d Ft\n", $a);
De még ez is megoldható szimpla print() utasítással.
Esetleg írhatunk elé is magyarázó szöveget, de az
megoldható a print() segítségével.
A következőkben azt szeretném, ha a számot 10 helyen ábrázolnánk,
akár hány számjegyből áll. Lássuk a következő példát:
$a = 3;
printf("%10d\n", $a);
A eredmény valami ilyesmi:
3
Hogy szemléletesebb legyen mi történik, írassuk ki a változó
előtt és utána egy pipe karaktert:
$a = 3;
printf("|%10d|\n", $a);
Az eredmény:
| 3|
Most írassuk ki egy háromjegyű számot:
$a = 345;
printf("|%10d|\n", $a);
Az eredmény:
| 345|
Néha szeretnénk a vezető nullákat megjeleníteni:
$a = 345;
printf("|%010d|\n", $a);
Vegyük észre a 10 elé írt nullát.
Az eredmény:
|0000000345|
===== Matematikai függvények =====
==== Alapértelmezett függvények ====
#!/usr/bin/perl
$a = 1;
$b = $a * 3.14 / 180;
print abs(-5), "\n"; # Abszolút érték
print atan2(1, 2), "\n"; # Inverz tanges radinában
print cos($b), "\n"; # Koszinusz érték radiánban
print exp(1), "\n"; # Exponens
print int(1.5), "\n";# Egész számmá konvertálás
print log(2), "\n"; # Természetes logaritmus értéke
print rand(5), "\n"; # Egy valós véletlen szám 0 és a megadott szám között.
# Ha nincs megadva felsőhatár, akkor az 1 lesz.
# A szám 0 és 1 közötti érték lesz
print sin($b), "\n"; # Színusz érték radiában
print sqrt(9), "\n"; # Gyök
print rand(5), "\n";
print rand(5), "\n";
srand; # A véletlenszám generátor beálllítása.
# Ha nincs érték megadva, akkor processzor ID és a
# az aktuális időből lesz kiszámítva.
srand(5);
print time, "\n"; # Az 1970 január 1 óta eltelt másodpercek száma
==== A Math::Trig modul használata ====
#!/usr/bin/perl
use Math::Trig;
print pi,"\n";
print sin(1), "\n";
===== Véletlen számok =====
A rand() függvény 0 és 1 között generál egy véletlen számot.
A rand() függvény paramétereként megadható a tartomány felső határa.
Ha 5-öt adunk meg, akkor 0-4-ig kapunk számokat.
Például a dobókocka dobások 1-6.
my $vel = int(rand(6))+1
print $vel . "\n";
===== Bevitel =====
A billentyűzetről szeretnénk adatokat olvasni.
A példa kedvéért, egy nevet fogunk beolvasni a billentyűzetről.
$nev = ;
Persze előtte írassuk ki mit szeretnénk:
print "Név: ";
$nev = ;
chomp ($nev = );
$nev = ;
chomp ($nev);
===== Szelekció =====
==== Szelekció if-el ====
Az if lehetővé teszi bizonyos utasítások végrehajtásának feltételhez kötését.
Az if utasítás általános alakja a következő:
if (feltétel) {
utasítás;
}
Legyen egy példa, ahol adott egy változó: "a". Ha az "a" változó nagyobb mint
5, szeretnénk a "Nagyobb" szót a képernyőre írni. Ha kisebb vagy egyenlő,
akkor nem teszünk semmit. Ekkor a program így nézhet ki:
if($a>5) {
print "Nagyobb";
}
A Perl nyelvben a blokk nyitó és záró kapcsos zárójeleket akkor is kötelező
kitenni, ha csak egyetlen utasítása van a szelekció törzsének. A
szelekció törzsében lévő utasítás akkor hajtódik végre, ha feltétel igaz.
Több utasítás esetén:
if (feltétel) {
utasítás1;
utasítás2;
...
utasításn;
}
Ha hamis feltétel esetén is szeretnénk végrehajtani egy utasítást, akkor
szükségünk lesz egy "else ágra", ahol megmondjuk mi történjen, ha
nem teljesül a feltétel.
if (feltétel) {
utasítás1;
}else {
utasítás2;
}
Számok összehasonlítása
$a = 3;
$b = 5;
if ($a == $b) {
print("Egyenlő");
}
Az összehasonlítás két egyenlőségjellel történik.
Szövegek összehasonlítása
$a = "alma";
$b = "körte";
if ($a eq $b) {
print("Egyenlő");
}
Szövegek összehasonlítására az "eq" operátort használjuk a "==" helyett.
Utasítás után tett if:
print "Meg van" if defined $a;
Igaz, hamis tárolása.
Hamis értékeke:
* 0
* '0'
* undef
* '' # Üres skaláris
* () # Üres lista
* ('')
==== elsif szerkezet ====
Az if az else ággal együtt egy vagy kétirányú elágazást képes megvalósítani.
Az elsif paranccsal ennél több irányú elágazás is megvalósítható.
my $a=5;
if($a==1){
print "egy";
}elsif($a==2){
print "kettő";
}elsif($a==3){
print "három";
}
else {
print "Más szám";
}
==== switch-case ====
A Perl nyelv alapértelmezésként nem tartalmaz switch-case szerkezetet.
A Core modulban azonban megvalósították ezt a szerkezetet.
A megvalósításhoz Switch csomagot kell használni. Példa:
use Switch;
my $ho = 2;
switch($ho)
{
case 1 {$maxnap = 31}
case 2 {$maxnap = 28}
case 3 {$maxnap = 31}
case 4 {$maxnap = 30}
case 5 {$maxnap = 31}
case 6 {$maxnap = 30}
case 7 {$maxnap = 31}
case 8 {$maxnap = 31}
case 9 {$maxnap = 30}
case 10 {$maxnap = 31}
case 11 {$maxnap = 30}
case 12 {$maxnap = 31}
else {$maxnap = 0}
}
==== unless ====
Olyan mint az if, csak az unless törzse, akkor hajtódik végre, ha
a feltétel hamis.
unless (feltétel) {
utasítások;
}
===== Iteráció =====
==== for ====
A for utasítást növekményes ciklusok megvalósítására használjuk.
A ciklus fejrésze három részre oszlik. Ezek a kezdőérték,
a feltétel és a növekmény.
for(kezdőérték; feltétel; növekmény) {
utasítás;
}
A Perl nyelvben a blokk nyitó "{" és blokk záró "}" karakterek megadása kötelező akkor is, ha csak egyetlen utasításunk van.
for($i=0; i$<10; $i++) {
print $i;
}
Adott számú ismétlés egyszerűen:
for (1..10) {
print "Helló\n";
}
Vételen ciklus:
for(;;) {
print "szilva\n";
}
==== while ====
$a = -1;
while($a != 0) {
print "Szám: ";
$a = ;
}
==== do-while ====
Akkor hajtódik végre, ha while paraméter igaz.
$a = 0;
do {
print "helló\n";
$a++;
} while ( $a<5);
==== Until ====
Az until ciklus akkor hajtódik végre, ha a paraméterként megkapott
feltétel hamis.
$a = 0;
until ( $a>=5) {
print "helló\n";
$a++;
}
==== foreach ====
foreach $i (1 .. 5) {
print "$i\n";
}
Hash feldolgozása:
%szotar = (
"körte" => "pear",
"alma" => "apple",
"ház" => "house",
"asztal" => "table"
);
foreach $key (sort keys %szotar) {
print "$szotar{$key}\n";
}
Tömb feldolgozása:
@szamok = (23, 43, 12, 21, 88, 31);
foreach $szam (sort @szamok) {
print "$szam\n";
}
==== last, next és redo ====
A while és a for ciklus vezérlésre találták ki a három utasítást: last, next és redo.
* last
* Megszakítja a ciklus futását.
* Mint a C nyelben a break.
* next
* Megszakítja a ciklust futását.
* Folytatja a következővel az elejéről.
* a c nyelvben ez a countinue
* redo
* megszakítja a ciklust futását
* folytatja a következővel az elejéről
* DE nem változtat semmit, feltételeken, nem növel semmit
===== Tömbök =====
{{:oktatas:programozás:perl:perl_tomb.png|}}
Üres tömb létrehozása:
my @tomb = ();
Tömb kezdőértékkel:
@nevek = ("Jószi", "Kati", "Mari", "Szilvi", "Feri");
Tömb egy eleme véletlenszerűen:
$elem = $tomb[ rand @tomb ];
Tömb mérete:
@tomb = ("egy", "kettő", "három");
print scalar(@tomb);
print scalar @tomb;
Tömb feldolgozása:
@gyumolcs = ("alma", "körte", "barack", "szilva");
foreach $resz (@gyumolcs) {
print $resz."\n";
}
Az első print @szamok kiírja az elemeket, de ha hozzáfűzök egy
karakterláncot, akkor ez is az elemek számát írja ki.
A print scalar(@szamok) utasítás pedig így, úgy is az elemek számát
írja ki.
#!/usr/bin/env perl -w
@szamok = (45, 23, 72, 54);
print @szamok;
print "\n";
print scalar(@szamok) . "\n";
A tömb utolsó indexe:
$utolsoIndex = $#szamok;
print $utolsoIndex;
Szöveg tömbként:
@napok = qw/hétfő kedd szerda csütörtök péntek szombat vasárnap/;
print @napok[0] . "\n";
print @napok[5] . "\n";
print @napok[-1] . "\n";
Tömb tartományokból:
@var_10 = (1..10);
@var_20 = (10..20);
@var_abc = (a..z);
Elem hozzáadása, törlése:
#!/usr/bin/env perl
my @zsak = ();
push(@zsak, "szilva");
push(@zsak, "körte");
push(@zsak, "alma");
# A tömb elejére:
unshift(@zsak, "barack");
# Utolsó elem törlése
pop(@zsak);
# Az első elem törlése:
shift(@zsak);
print "Tömb mérete: " . scalar @zsak . "\n";
foreach $elem (@zsak) {
print $elem . "\n";
}
Egyik tömbből a másikba:
#!/usr/bin/env perl
@napok = qw/hétfő kedd szerda csütörtök péntek szombat vasárnap/;
@hetkoznap = @napok[0, 1, 2, 3, 4];
foreach $elem (@hetkoznap) {
print $elem . "\n";
}
Adatok cseréje:
@szamok = (1..20);
print "Előtte - @szamok\n";
splice(@szamok, 5, 5, 21..25);
print "Utána - @szamok\n";
Előtte - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Utána - 1 2 3 4 5 21 22 23 24 25 11 12 13 14 15 16 17 18 19 20
Átalakítás karakterlánccá:
@napok = qw/hétfő kedd szerda csütörtök péntek szombat vasárnap/;
$string = join ' ', @napok;
print $string;
Rendezés:
@zsak = ("körte", "szilva", "alma", "barack", "meggy", "málna");
@zsak = sort(@zsak);
print "@zsak";
Eredmény:
alma barack körte meggy málna szilva
Egyesítés:
@egy = ("szilva", "alma");
@ketto = ("körte", "barack");
@mind = (@egy, @ketto);
print "@mind\n";
==== Elem törlése ====
#!/usr/bin/perl
my @list = ();
push(@list, "alma");
push(@list, "körte");
push(@list, "szilva");
push(@list, "barack");
push(@list, "szilva");
push(@list, "banán");
print "@list\n";
my @delIndexes = reverse(grep { $list[$_] eq 'szilva' } 0..$#list);
foreach $item (@delIndexes) {
splice (@list,$item,1);
}
print "@list\n";
===== Karakterláncok kezelése =====
==== Karakterlánc állandók ====
Nem történik változó behelyettesítés:
'tegyem, vagy ne tegyem'
q/tegyem, vagy ne tegyem/
q#tegyem, vagy ne tegyem#
q(tegyem, vagy ne tegyem)
Van változó behelyettesítés:
"tegyem, vagy ne tegyem"
qq/tegyem, vagy ne tegyem/
qq^tegyem, vagy ne tegyem^
==== Darabolás ====
$sor = "Nagy József:nagy:titok";
@adatok = split(/:/, $sor);
print @adatok[0]."\n";
print @adatok[1]."\n";
print @adatok[2]."\n";
my ($fullName, $user, $pass) = split(/:/, $sor);
==== Sorvége eltávolítása ====
chomp($str);
==== Összehasonlítások ====
^ String operátor ^ Numerikus operátor ^
| eq | == |
| ne | != |
| gt | > |
| lt | < |
| ge | >= |
| le | <= |
print "Név: ";
$nev = <>;
chomp($nev);
if (lc($nev) eq "kati") {
print "Üdv Kati!\n";
}else {
print "Ki vagy te?\n";
}
==== Idézőjelek ====
^ Általában ^ Perlben így is lehet ^ Jelentés, megjegyzés ^
| '' | q{} | szöveg literál, szó szerinti szöveg |
| "" | qq{} | szöveg literál, változó-behelyettesítéssel |
| `` | qx{} | parancs, az adott szöveget, mint egy shell parancssort végrehajtja |
| | qw{} | szólista készítése szövegből |
| // | m{} | mintaillesztés változó-behelyettesítéssel |
| | s{}{} | csere, változó-behelyettesítés is van |
| | tr{}{} | egy betű cseréje; A szöveg lesz a cseretábla |
==== Hossz ====
#!/usr/bin/perl
$str = "barka";
$size = length $str;
print "Méret: $size\n";
Ha egy betű nincs az angol ábécében, mint például az "ű" betű, annak
mérete 2 lesz:
print "Méret: " . length "ű";
Erre megoldást jelent, ha bekapcsoljuk a use utf8 utasítással az UTF-8 karakterek kezelését.
Az eredmény így már 1 lesz.
Ekkor azonban a kimeneten a példában látható "é" betű elromlik, rosszul íródik ki.
A binmode(STDOUT, ":utf8") utasítással a kimenetet is UTF-8-ra állítom és a probléma
megoldva:
#!/usr/bin/perl
use utf8;
binmode(STDOUT, ":utf8");
print "Méret: " . length "ű";
==== Nagybetűssé alakítás ====
#!/usr/bin/perl
$str = "akarat";
$upStr = uc $str;
print "Nagybetűsen: $upStr\n";
Ékezetes betűk esetén itt is használható az utf8:
#!/usr/bin/perl
use utf8;
binmode(STDOUT, ":utf8");
print "Nagybetűs: " . uc "árvíztűrő tükörfúrógép";
==== Kisbetűssé alakítás ====
#!/usr/bin/perl
$str = "AKARAT";
$upStr = lc $str;
print "Kisbetűsen: $upStr\n";
Ékezetes betűk esetén itt is használható az utf8:
#!/usr/bin/perl
use utf8;
binmode(STDOUT, ":utf8");
print "Kisbetűs: " . uc "ÁRVÍZTŰRŐ TÜKÖRFÚRÓGÉP";
==== Összehasonlítás ====
if($user eq "vki") {
print("Ok\n");
}else {
print("Nem jó\n");
}
if($user eq "vki" && $pass eq "titok") {
print("Ok\n");
}else {
print("Nem jó\n");
}
==== Konkatenálás ====
#!/usr/bin perl
$egy = "első";
$ketto = "kettő";
$harom = $egy.$ketto;
print("$harom\n");
#!/usr/bin perl
$egy = "első";
$ketto = "kettő";
$harom = $egy." ".$ketto;
print("$harom\n");
$harom = "$egy $ketto";
==== Trim ====
Whitespace karakterek törlése.
Balról:
$szoveg =~ s/^\s+//;
Jobbról:
$sz9veg =~ s/\s+$//;
Mindkét oldalról:
$szoveg =~ s/^\s+|\s+$//g;
==== Karaktersorozat bejárása ====
#!/usr/bin/perl
use utf8;
binmode(STDOUT, ":utf8");
$szoveg = "Árnika";
for($i=0; $i < length($szoveg); $i++) {
print substr($szoveg, $i, 1) . "\n";
}
print "\n";
foreach $kar (split //, $szoveg) {
print "$kar\n";
}
print "\n";
===== Fájlkezelés =====
==== Olvasás fájlból ====
open FAJLNEV, "<", $userfile or die $!;
while() {
print $_."\n";
}
==== Írás fájlba ====
open FILEID, ">", "filenev.txt" or die $!;
print FILEID "szöveg\n";
close(FILEID);
==== Egyéb példák ====
$file = '/etc/passwd'; # A fájl neve
open(INFO, $file); # A fájl megnyitása
@lines = ; # Olvasás egy tömbbe
close(INFO); # Fájl bezárása
print @lines; # A tömb kiíratása
open(INFO, $file); # Megnyitás beolvasásra
open(INFO, ">$file"); # Megnyitás kiírásra
open(INFO, ">>$file"); # Megnyitás hozzáfűzésre
open(INFO, "<$file"); # Megnyitás beolvasásra
open(INFO, '-'); # Az alapértelmezett bemenet megnyitása
open(INFO, '>-'); # Az alapértelmezett kimenet megnyitása
===== Függvények =====
A Perl függvények összetartozó utasítások. Ez "sub" utasítással vezetjük be,
majd megadjuk a függvény nevét. A függvény neve után nem kell "()" zárójel páros,
akár van paraméter, akár nincs. Ha mégis teszünk zárójelet, az interpreter
nem szól érte.
sub sajatfuggvenynev {
# utasítások
}
A függvény meghívása viszont zárójelekkel történik:
sajatfuggvenynev();
Régebben az 5.0 Perl verzióknál a függvényeket egy "&" karakter
bevezetésével kell meghívni:
&sajatfuggvenynev();
A függvények beépíthetők más utasításokba, a függvények
eredménye pedig összefűzhetők karaktersorozatokkal:
print osszead()."\n";
sub osszead {
return 3 + 5;
}
A Perl függvényeknek nem lehet formális paraméterlistája.
Jó kérdés, hogy akkor hogyan vesszük át az aktuális
paramétereket. A válasz egyszerű. A paramétereket a @_
tömbben fogjuk megkapni. Ha egy függvény alap és magasság értékeket fogad,
azokat így dolgozhatjuk fel:
sub szamitTerulet {
$alap = @_[0];
$magassag = @_[1];
print "Terület: ".($alap * $magassag) / 2;
}
szamitTerulet(30, 35);
A @_ használata:
#!/usr/bin/perl
use strict;
use warnings;
&sf(35);
sub sf() {
print "Szám: @_\n";
}
A fenti példában a @_ változóban vesszük át az értéket.
Újabb példa:
#!/usr/local/bin/perl -w
my $temp = sajat_fuggveny();
print "A temp: @$temp.\n";
sub sajat_fuggveny {
my $entry = shift;
my ($val1, $val2, $val3) = qw(első második harmadik);
my $ret = [$val1, $val2, $val3];
return $ret;
}
Két paraméter shifttel:
sub haromszogKerulet {
my $alap = shift;
my $magassag = shift;
return ($alap * $magassag)/2;
}
sub haromszogKerulet {
my ($aOladl, $bOldal, $cOldal) = @_;
return $aOldal+$bOldal+$cOldal;
}
Paraméterek feldolgozása foreach utasítással:
#!/usr/bin/env perl
use strict;
use warnings;
csinal(45, 23, 88, 92);
sub csinal {
foreach(@_) {
print $_."\n";
}
}
Másként:
#!/usr/bin/env perl
csinal(45, 31, 29, 21, 82);
sub csinal {
foreach my $szam (@_) {
print $szam."\n";
}
}
A **return** utasítással visszaadhatunk egy kívánt értéket.
Ahogy azt fentebb láttuk, az utasítás használata nem kötelező.
print osszead(3, 5)."\n";
sub osszead() {
return $_[0] + $_[1];
}
Az átvett paraméterek értékét a $_[0], $_[1], stb. változókban kapjuk meg.
Az unless és if utasítással szabályozhatjuk a return utasítást:
#!/usr/bin/env perl
sub egy {
return "nincs paraméter" unless @_;
return "siker, a paraméter helyes, azaz 34" if @_[0] eq 34;
return "van valamilyen paraméter" if @_;
}
print egy(34);
**Tömb** visszaadott értékként:
#!/usr/bin/perl
use strict;
use warnings;
# A szubrutin prototípusa:
sub get_two_arrays();
# Két változóban kapjuk az eredményt
my (@elso, @masodik) = leker_ket_tomb();
print "Első: @elso\n";
print "Második: @masodik\n";
sub leker_ket_tomb() {
my @tomb1 = ("a", "b", "c", "d", "e");
my @tomb2 = (1, 2, 3, 4, 5);
return (@tomb1, @tomb2);
}
**hash** függvény paramétereként:
#!/usr/bin/env perl
sub kiAdatok {
my %ember = @_;
foreach my $kulcs ( keys %ember) {
my $ertek = $ember{$kulcs};
print "$kulcs : $ertek\n";
}
}
%janos = (
'név' => 'János',
'kor' => 28,
'fizetés' => 875000.0
);
kiAdatok(%janos);
===== Változók hatásköre =====
#!/usr/bin/env perl
$szam = 45; # globális változó
sub ki {
my $kor = 35; # helyi változó
my ($a, $b, $c); # helyi változó
$a = 100; $b = 200; $c = 300;
$fizetes = 885000.0;
}
ki();
print $fizetes;
Láthatjuk, ha nem használjuk a my kulcsszót, akkor
a függvényben elsőnek használt változó globális lesz.
Ezen változtathatunk ha a local kulcsszót használjuk.
A local helyi változók létrehozására kitalált direktíva.
#!/usr/bin/env perl
sub ki {
local $fizetes = 885000.0;
}
ki();
print $fizetes;
A **state** kulcsszóval egy függvény értéke, többszöri hívás esetén is azonos
marad. a state a Perl 5.9.4. verziója óta használható.
#!/usr/bin/env perl
use feature 'state';
sub csinal {
state $szam = 0;
print $szam;
$szam++;
}
for (1..5) {
csinal();
}
===== Vizsgálat =====
Néhány egyszerű kapcsolóval többféle feltételvizsgálatokat hozhatunk létre
állományokra és könyvtárakra. Például egy könyvtár létezését a
következő módon vizsgálhatjuk meg:
if(-d "/home/username") {
}
^ A vizsgálat során használható kapcsolók ^^
^ Kapcsoló ^ Leírás ^
| -r | A fájl olvasható tényleges uid/gid számára. |
| -w | A fájl írható a tényleges uid/gid számára. |
| -x | A fájl futtatható a tényleges uid/gid számára |
| -o | A fájl tulajdonosa a tényleges uid |
| -R | A fájl olvasható a valódi uid/gid számára. |
| -W | A fájl olvasható a valódi uid/gid számára |
| -X | A fájl futtatható a valódi uid/gid számára |
| -O | A fájl tulajdonosa a valódi uid |
| -e | A fájl létezik |
| -z | A fájl nulla méretű. (üres) |
| -s | A fájl nem nulla méretű (visszatér a mérettel byte-okban) |
| -f | A fájl szimpla ASCII fájl |
| -d | A fájl egy könyvtár |
| -l | A fájl egy szimbolikus link |
| -p | A fájl egy elnevezett pipe (FIFO), vagy a fájlkezelője pipe. |
| -S | A fájl egy socket |
| -b | A fájl egy speciális blokkfájl. |
| -c | A fájl egy speciális karakterfájl |
| -t | A fájl nyitva van egy tty-on. |
| -u | A fájlon be van állítva a setuid bit. |
| -g | A fájlon be van állítva a setgid bit. |
| -k | A fájlon be van állítva a sticky bit. |
| -T | A fájl egy ASCII szöveges fájl (persze ez csak becslés) |
| -B | A fájl egy bináris fájl (szemben a -T kapcsolóval) |
| -M | A fájl készítési ideje és a módosítás ideje közötti idő (napokban) |
| -A | Egyezik a hozzáférési idő |
| -C | Az inode változás ideje egyezik (Unix, más platformok esetén ez különbözhet |
#!/usr/bin/perl
if(-d "/home/username") {
print "A felhasználói könyvtár létezik\n";
}
if ( -e $konyvtar and -d $konyvtar) {
print "A könyvtár létezik";
}
===== Dátum =====
#!/usr/bin/perl
# 0 1 2 3 4 5 6 7 8
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%02d-%02d %02d:%02d:%02d\n", $year + 1900, ++$mon, $mday, $hour, $min, $sec);
use POSIX qw(strftime);
$now_string = strftime "%a %b %e %H:%M:%S %Y", localtime;
# esetleg GMT formájú:
$now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
#!/usr/bin/perl -w
# 0 1 2 3 4 5 6 7 8
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
$year += 1900;
$mon++;
$mon = sprintf("%02d", $mon);
$mday = sprintf("%02d", $mday);
$hour = sprintf("%02d", $hour);
$min = sprintf("%02d", $min);
$sec = sprintf("%02d", $sec);
print "$year-$mon-$mday $hour:$min:$sec\n";
A sprintf() a vezető nullák beállításához szükséges.
===== Hash =====
my %eletkor = ( "Jani" => 37, "Gabor" => 25 );
print $eletkor{Jani}."\n";
print $eletkor{Gabor}."\n";
#Üres hash:
my %hash1 = ();
print %hash1;
Ellenőrizzük, hogy adott kulcs létezik-e:
#!/usr/bin/perl
use strict;
use warnings;
my %eletkor = (
"Jani" => 37,
"Gabor" => 25,
"Sanyi" => 47
);
if(exists($eletkor{"Gabor"}))
{
print "Van Gábor\n";
print "$eletkor{Gabor}\n";
}
else
{
print "Nincs Gábor\n";
}
Az értékeke kiíratása:
print(join(', ', keys %eletkor),"\n");
Kiíratás rendezve:
#!/usr/bin/perl
use strict;
use warnings;
my %eletkor = (
"Sanyi" => 47,
"Tibor" => 29,
"Lajos" => 28,
"Jani" => 37,
"Gabor" => 25
);
print(join(', ',sort keys %eletkor),"\n");
Rendezés újra:
#!/usr/bin/perl
my %eletkor = (
"Sanyi" => 47,
"Tibor" => 29,
"Lajos" => 28,
"Jani" => 37,
"Gabor" => 25
);
my @rendezett = sort keys %eletkor;
foreach my $kulcs (@rendezett)
{
print $kulcs."\n";
}
Méret:
#!/usr/bin/perl
my %eletkor = (
"Sanyi" => 47,
"Tibor" => 29,
"Lajos" => 28,
"Jani" => 37,
"Gabor" => 25
);
my $meret = scalar keys %eletkor;
print $meret."\n";
Törlés:
#!/usr/bin/perl
my %eletkor = (
"Sanyi" => 47,
"Tibor" => 29,
"Lajos" => 28,
"Jani" => 37,
"Gabor" => 25
);
print scalar keys %eletkor , "\n";
delete($eletkor{"Tibor"});
print scalar keys %eletkor , "\n";
===== Több fájl =====
#!/usr/bin/perl
require "fg.pl";
kiirNev();
kiirCim();
sub kiirNev()
{
print "Nagy József\n";
}
sub kiirCim()
{
print "Budapest\n";
}
1;
Az fg.pl állományra nem szükséges futtatási jog.
A main.pl állományra futtatási jog szükséges:
chmod u+x main.pl
A require parancsról több információ:
perldoc -f require
perldoc -q require