[[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