Buradan
Transkript
Buradan
Yazar : Ertan TÜRKMEN Güncelleme: TD Software (www.tdsoftware.tr.cx) 1.GİRİŞ Perl Komutları Nasıl Yazılır? Beğendiğiniz bir editörle yazabilirsiniz. İlk satırda perl'un icra edilebilir dosyasının sistemdeki tam yolu verilir. Satırın başına( #! ) özel karakterleri mutlaka yazılmalıdır. Örnek : #!/usr/bin/perl gibi... Kodlama bittikten sonra editörden çıkılır ve Unix ve benzeri sistemlerde o dosyaya icra hakkı vermeniz gerekir. Varsayalım ki program adı deneme.pl olsun; chmod +x deneme.pl komutu bu işlemi yerine getirir. Program Nasıl Çalışır? Komut satırından program adını girip Enter tuşuna basınız. Örnek : deneme.pl Örnek program : #!/usr/local/bin/perl $girilensatir = <STDIN>; print($girilensatir); Bu programın ilk satırında programın icrası için gereken dosyanın yeri belirtilmiştir. İkinci satırda klavyeden girilen değer $girilensatir değişkenine aktarılır. (Burada klavyeden merhaba yazalım). Üçüncü satırda ise bu değer ekrana yazdırılır. Ekrandaki görüntü şu şekildedir: > deneme.pl > merhaba > merhaba Açıklama satırları nasıl belirtilir. Açıklama yapmak amacıyla kullanacağımız satırların başına # işareti koyarız. Örnek : # bu bir açıklama satırıdır # perl tarafından dikkate alınmaz Bu durumda önceki programımızı şu şekilde kodlayalım; #!/usr/local/bin/perl #Bu program klavyeden girileni #ekrana yazar. $girilensatir = <STDIN>; print($girilensatir); Programın çalışması bir önceki ile tamamen aynıdır. # ile başlayan satırlar sadece bizi aydınlatmak, not tutmak içindir. Perl bu satırları değerlendirmeden geçer. Şimdi şu satırı ele alalım; $girilensatir = <STDIN>; Bu satir bir perl ifadesidir(statement) her bir parçasına($girilensatir,=,<STDIN>,;) ise gösterge (token) denir. $girilensatir bir skalar değişkeni belirtir. $ isareti değişkenin skalar olduğunu girilensatir ise değişkenin adını belirler. = göstergesi kendisinin (bize göre) sağındaki ifadeyi solundakine ata anlamı taşır. <STDIN> standart giriş elemanını yani klavyeden girişi ifade eder. Son olarak ; göstergesi ise ifadenin bitişini gösterir ve ifade sonlarında mutlaka bulunmalıdır aksi takdirde hata mesajı alırsınız. Yukarıdaki açıklamalar tüm perl benzer ifadelerinde geçerlidir. Yazım sırasında istisnai durumlar dışında karakter aralarında boşluk, tab v.b whitespaces karakterleri kullanılabilir.Aralardaki boşluk sayısı önemli değildir. Gelelim yazdırmaya; Standart çıktı(ekran)ya yazdırma görevini print yapar. print($girilensatir); ifadesiyle $girilensatir skalar değiskeninin içeriği ekrana yazdırılır. Aslında print fonksiyon olarak çalışır. $girilensatir 'ı ise arguman olarak kullanır. Arguman 1 den fazlada olabilir. Print ($girilensatir, $girilensatir); ifadesinde 2 arguman kullanılmıştır. Her ikisi de klavye girişini alan $girilensatir değişkenidir. Bu durumda busatırın çalışması anında $girilensatir değeri, ekrana 2 defa yazdırılır. 2- SABİT VE DEĞİŞKENLER 1.Sabitler A)Sayısal Sabitler: Sayısal sabitler,programın çalışması esnasında gereken sayısal sabit değerlerdir. Perl 8 ve 16 tabanlı sayısal değerlerin kullanımını da sağlar. 1245 100.45 .000034 043 0x23 ...gibi B)String Sabitler: String sabitler,programın çalışması esnasında gereken alfasayısal sabit değerlerdir. Alfabetik ve Alfabetik/sayısal/özelkarakter karışımı olabilirler. Tırnak içindeki ifadelerdir. Perl stringlerde; Tek, çift, geri tırnak kullanır. Bunlar birlikte de kullanılabilirler. Kurallarını göreceğiz. Örnek: 'Ertan Türkmen' "Ertan Türkmen" "Dedi ki, \"O Ankara'dan geldi.\"" 'Ahmet Trabzon\'ludur' ...gibi stringlerde EscapeSequence denilen özel işlevli karakterlerde kullanılır. Escape SequeNCe karakterlerinden bazıları ve anlamları: \a \b \e \f \n \r \t \v Alarm Backspace -geriEscape -çıkışForm Feed -form besleme Newline -yeni satırCarriage return -satır sonuTab - x karakter atla Vertical Tab - dikey atla - ilerleyen derslerde konuyla ilgili örnekler görecek ve daha iyi anlayacağız. 2.Değişkenler a)Skalar değişkenler : İçersinde değişebilen değerler bulunduran birimlerdir. İlk karakteri $ işaretidir.Bu karakterden sonra en az 1 alfabetik karakter bulunmalıdır. Değişken adında kural olarak bu karakterlerden hemen sonra alfabetik, sayısal karakterler ve _ karakteri kullanılabilir. Değişken uzunluğu serbesttir. Örneğin; $ad, $ad_soyad, $a1 ad $ $47x $_ad $ad! # $ #$ # # #! gibi değişken adlari geçerli olup aşağıdakiler geçersizdir. karakteri olmadığından dan sonra en az 1 alfabetik karakter gerektiğinden 2.karakter sayısal olamaz 2.karakter alfabetik olmalı karakteri kullanılamaz Not : Küçük ve büyük harf kullanımı önemlidir ve farklı değişkenleri temsil ederler. Bu demektir ki; $AD ile $Ad ve $ad farklı değişkenlerdir. Değişkenlere değer atama: Eşitliğin bize göre sağındaki değer (sayısal/alfabetik/karışık olabilir) solundaki değişkenin içine konur. Aşağıdaki ifadeyi inceleyiniz. $ADI_SOYADI = "Ertan TURKMEN"; $ADI_SOYADI değişkeni içindeki değer "Ertan TURKMEN" dir. benzer şekilde, $MAAS = 125000; $MAAS değişkeni içeriği 125000 dir. Not : Değişkenin içinde önceden bir değer varsa,önceki değer silinir, son atanan değer geçerli olur. Aritmetik Operatörler: Perl de kullanılan TEMEL aritmetik operatörler; Toplama + ÇıkartmaÇarpma * Bölme / dir. Örnek program : Verilen değerin Km ve Mil cinsinden çevirimini yapar. Adı milkm.pl olsun. #!/usr/local/bin/perl print ("Mesafeyi giriniz: \n"); $mesafe = <STDIN>; chop ($mesafe); # # # # chop fonksiyonu giriş sonundaki karakteri atar programımızda son karakter Enter tuşuna bastığımız için yeni satır (\n) karakteri olduğundan onu atar(siler). $mil = $mesafe * 0.6214; $km = $mesafe * 1.609; print ($mesafe, " km = ", $mil, " mil\n"); print ($mesafe, " mil = ", $km, " km\n"); Not : Program satırlarında kullanılan "\n" göstergesi alt satıra geçişi sağlayan yeni satır karakteridir. Çalışması: >milkm >Mesafeyi giriniz: >10 >10 km = 6.2139999999999995 mil >10 mil = 16.09 km > a.1)Tamsayi (integer) Skalar değişkenler: İçerisinde tamsayı sabit ve literal bulundurabilirler. integerlar kayar noktalı (floating-point--birazdan inceleyeceğiz--)değerler gibi işlem görürler. Örnek program: adı prg.pl olsun... #!/usr/local/bin/perl $deger = 1234567890; print ("1.değer: ", $deger, "\n"); $deger = 1234567890123456; print ("2.değer: ", $deger, "\n"); $deger = 12345678901234567890; print ("3.değer: ", $deger, "\n"); Çalışması : > prg >1.değer: 1234567890 >2.değer: 1234567890123456 >3.değer: 12345678901234567168 çıktısı verir. Görüldüğü gibi ilk 2 değerde sorun yoktur.3.değer yanlış sonuç üretir. Çünkü tamsayı için fazla değer içermektedir. a.1)Kayar Noktalı (floating-point) Skalar değişkenler: En fazla 16 rakam kabul edebilirler. Bu değişkenler tamsayı, ondalıklı, exponent(e üzeri) ve -/+ işaretli değerleri saklayabilirler. Örneğin, aşağıdaki değerlerle işlem yapabilirler. 11.4 , -275 , -0.3 , .3 , 3. , 5.47e+03 , ...v.b. Örnek program : Adı prgsk1.pl olsun, #!/usr/local/bin/perl $deger = 34.0; print ("1. deger ", $deger, "\n"); $deger = 114.6e-01; print ("2. deger ", $deger, "\n"); $deger = 178.263e+19; print ("3. deger ", $deger, "\n"); $deger = 123456789000000000000000000000; print ("4. deger ", $deger, "\n"); $deger = 1.23e+999; print ("5. deger ", $deger, "\n"); $deger = 1.23e-999; print ("6. deger ", $deger, "\n"); Programın > > > > > > > > Çalışması : prgsk1.pl 1. deger 34 2. deger 11.460000000000001 3. deger 1.7826300000000001e+21 4. deger 1.2345678899999999e+29 5. deger Infinity 6. deger 0 b)String değişkenler: String (karakter/karakterler içeren dizi) içerirler. Bu değerler alfabetik ve sayısal sabit veya değişken olabilirler. Ör1: $AD_SOYAD = "Ertan TURKMEN"; komutuyla "Ertan TURKMEN" stringi $AD_SOYAD string değişkenine atanır. Ör2: $number = 11; $text = "Bu text sayı içerir.İçerdiği sayı $number."; komutlarının icrası sonucu $number'a 11 sayısı atanır. $text değişkenine ise "Bu text sayı içerir. İçerdiği sayı $number." Stringi atanır. Sonuçta $text'in içeriği şudur. "Bu text sayı içerir.İçerdiği sayı 11." Stringlerde de Escape Sequence karakterler kullanılır. Bunlar aşağıdadır : \a Zil sesi \b Backspace \cn Ctrl+n karakteri \e Escape \E \L, \U or \Q etkisini sonlandır \f Form feed \l Sonraki harfi küçüğe çevirir \L Sonraki tüm harfleri küçüğe çevirir \n newline - Yeni Satır \rCarriage \Q \t Tab \u \U \v return Özel örnek karakterleri arama Sonraki harfi büyüğe çevir Sonraki tüm harfleri büyüğe çevir vertical tab Tek ve Çift tırnaklı string farkı: Bunu örnekle inceleyelim. Ör1: Ör2: $string = "Bir stringdir"; $text = "Bu $string"; # $text'in içeriği "Bu Bir stringdir" $text = 'Bu bir $string'; #$text'in içeriği 'Bu bir $string' İki örnek arasında fark açıkça görülmektedir. Tek tırnak içindeki string aynen saklanır. Değişken ve hatta \n gibi karakterlerde kendi özelliklerini icra eder şekilde kullanılamaz. (sadece \ ve ' karakterleri hariç) Ör3: Ör4: Ör5: $text = 'Bu string.\n'; $text içeriği: Bu string .\n şeklindedir. $text = 'Burada \', tek tırnak karakteri var'; $text içeriği: Burada ', tek tırnak karakteri var $text = 'Stringin son karakteri backslash \\'; $text içeriği: Stringin son karakteri backslash \ şeklindedir. String ve Sayısal değerlerde değiştirilebilirlik: Örnekle inceleyelim. $string = "43"; $Sayı = 28; $result = $string + $Sayı; $result içeriği 71 dir. Bir de şu örneği inceleyelim: $number = <STDIN>; #klavyeden giriş bekler 22 girdik diyelim # $number içeriği 22\n dir (\n enter tusu) chop ($number); # $number içeriği su anda 22 $result = $number + 1; #$result içeriği 23 Şöyle bir atama sonucunda ise : $result = "hello" * 5; $result içeriği 0 dır. çünkü hello sayısal olmadığı için sayısal değeri 0 dır Eğer string ifadede sayısal ve alfabetik değer varsa, $result = "12o34"; gibi.. Bu durumda ortadaki o harfi öncesi geçerlidir. $result içeriği 12’dir. ALTERNATİF STRİNG AYRAÇLARI Aşağıdaki örneğe bakalım; $say = 5; print ("$say\n"); # 5 basar print ('$say\n'); # $var\n basar örnekte ' ve " ayraçlarını görüyoruz. Perl başka ayraç elemanları da sunar. Bu işlev için, q kullanıp sonraki ayraç elemanını belirleyebiliriz. q!merhaba $kim! gibi... bu ifade ile aşağıdaki ifade aynıdır. 'merhaba $kim' String sınırlayıcı olarak qq kullanırız. qq/This string contains $var./ Burada / karakteri stringi ayırır(sınırlar). Stringi kelimelere ayırma-kesme- işlevini qw ile yaparız. Aşağıdaki iki satır aynıdır. @kelimeler = qw/Bu bir cümledir/; @kelimeler = split(' ', q/Bu bir cümledir/); her iki durumda da @kelimeler ' e şu liste atanır; ("Bu ", " bir ", " cümledir") << KULLANARAK STRİNG TANIMLAMA << işareti ile string başı tanımlanır. Bu string boş satır görene kadar devam eder. Örnek: $A = << here is the string bu ikinci satır } $A içeriği yandaki ilk iki satırdır. üçüncü satır dördüncü satır << sonra konacak string, string sonunu belirler. Örnek: $str = <<END (veya şu şekilde <<'END' ) bu birinci satır bu ikinci satır END (string sonu) Şu da doğrudur. $end = "END"; $str = <<"$end" bu ilk satır bu ikinci satır END Şu kullanıma bakın; print <<END Merhaba! Iyi calışmalar! END çıktısı Merhaba! Iyi calışmalar! print <<END x 2 Merhaba! END Çıktısı Merhaba! Merhaba! $satır = <<END1 <<END2 birinci kısım END1 ikinci kısım END2 $satır içeriği: Birinci kısım İkinci kısım Not: \n dahildir. Not2: << aralarında boşluk olmamalıdır. Koşul ve Kontrol Deyimleri -- Dallanma ve Yönlendirme 1. if Deyimi : if ($sayı) { print ("Sayı sıfır değil..\n"); } Yukarda bir if deyimli perl program parçası görüyorsunuz. if deyimi yanında () parentez içersindeki değer veya değişken sınanır.Parantezler arası bu kısım şart ifadesidir (Örneğimizde ($sayı). Bu ifadenin içerdiği sonuç doğru ise oklu parentezler (Blokbaşı ve sonunu ifade eder ki kullanılması şarttır) içerisindeki kısım blok olarak icra edilir. Sonuç yanlış ise Blok dışına geçilir. Sonucun doğru(true)olması demek parentez içi değerin 0 olmaması demektir. Değer 0 ise sonuçyanlıştır (false). Örnek Program : Program adı ifprg.pl olsun #!/usr/local/bin/perl print ("Bir sayı giriniz:\n"); $sayi = <STDIN>; #Program calıştığında burada 7 girelim chop ($sayi); if ($sayi) { print ("Girilen sayı sıfır değil.\n"); } print ("Program sonu...\n"); Çalışması: >ifprg >Bir sayı giriniz: >7 >Girilen sayı sıfır değil. >Program sonu... > if deyiminin koşul ifadesi kısmında karşılaştırmalarda yapılır. Örnek : if ($sayi == 5) { .... } Yukarıdaki ifadede $sayı değişkenindeki değerin 5'e eşit olup olmadığı sınanmaktadır. == göstergesi eşitlik anlamındadır. Buna benzer şekilde büyük ve küçüklük sınamaları da yapılır. Ör : if ( $sayi > 5 ) .. Bu kullanımda sınama sonucu ne ise ona göre işlem yapılır. Örneğin, sonuç doğru ise oklu parantez içindeki blok icra edilir. Aksi takdirde doğrudan blok dışına atlanır. Örnek program : Program adı ifprg2.pl olsun, #!/usr/local/bin/perl print ("Sayı gir:\n"); $sayi1 = <STDIN>; chop ($sayi ); print ("Başka bir sayı gir:\n"); $sayi2 = <STDIN>; chop ($sayi2); if ($sayi1 == $sayi2) { print ("Girilen iki sayı eşit.\n"); } print ("Program sonu.\n"); Çalışması : >ifprg2 >Sayı gir: >17 >Başka bir sayı gir: >17 >Girilen iki sayı eşit. >Program sonu. > IF ve ELSE kullanarak dallanma: Genel format : if (koşul) { Koşul doğruysa icra edilen kısım; } else { Koşul yanlışsa icra edilen kısım; } Örnek program : program adı ifprg3.pl olsun #!/usr/local/bin/perl print ("Bir sayı giriniz:\n"); $sayi1 = <STDIN>; chop ($sayi1); print ("Baska bir sayı giriniz:\n"); $sayi2 = <STDIN>; chop ($sayi2); if ($sayi1 == $sayi2) { print ("Iki sayı eşittir.\n"); } else { print ("Iki sayı eşit değildir.\n"); } print ("Program sonu.\n"); Çalışması ; >ifprg3 >Bir sayı giriniz: >17 >Baska bir sayı giriniz: >18 >Iki sayı eşit değildir. >Program sonu. > ÇOKLU DALLANMA if-elsif-else kullanımı: Genel Formatı : if (koşul1) { koşul1 dogru ise icra edilir } elsif (koşul2) { koşul2 dogru ise icra edilir } elsif (koşul3) { koşul3 dogru ise icra edilir ... else } { Hiçbir koşul doğu değil ise icra edilir } Örnek program: Program adı ifprg4.pl olsun #!/usr/local/bin/perl print ("Bir sayı giriniz:\n"); $sayi1 = <STDIN>; chop ($sayi1); print ("Baska bir sayı giriniz:\n"); $sayi2 = <STDIN>; chop ($sayi2); if ($sayi1 == $sayi2) { print ("Sayılar eşit.\n"); } elsif ($sayi1 == $sayi2 + 1) { print ("Birinci sayi 1 buyuk.\n"); } elsif ($sayi1 + 1 == $sayi2) { print ("Ikinci sayi 1 buyuk.\n"); } else { print ("Sayilar eşit değil.\n"); } print ("Program sonu.\n"); Çalışması: >ifprg4 >Bir sayı giriniz: >17 >Baska bir sayı giriniz: >18 >Ikinci sayi 1 buyuk. >Program sonu. > NOT : Bu konunun devamını 9.Derste göreceğiz. DÖNGÜLER While Döngüsü: Koşul ifadesi doğru (true) ise blok içi uygulanır. Değilse blok dışına(sonrasına) çıkılır. while ($sayi == 5) { print ("Sayı 5!\n"); } Yukarıdaki örnekte koşul ifadesi $sayı değişkeninin 5’e eşitliğini test ediyor. Eğer 5 ise (true) oklu parantez içine (bloğa) geçilerek icra edilir. % değilse (false) blok dışına çıkılır. Örnek Program : Program adı wh_dongu1.pl olsun. #!/usr/local/bin/perl $sayi = 0; $sayac = 1; print ("Bu satır döngü başlamadan evvel yazıldı.\n"); while ($sayi == 0) { print ("Dongu sayac değeri ", $sayac, "\n"); if ($sayac == 3) { $sayi = 1; } $sayac = $sayac + 1; } print ("Döngüden çıktık.\n"); Çalışması : >wh_dongu1 >Bu satır döngü başlamadan evvel yazıldı. >Dongu sayac değeri 1 >Dongu sayac değeri 2 >Dongu sayac değeri 3 >Döngüden çıktık. > Until Döngüsü : Genel formatı : until (koşul ifadesi) { koşul ifadesi sonucu yanlış(true) ise blok içi uygulanır koşul doğru olunca blok dışına çıkılır } Örnek Program : Program adı untilprg.pl olsun #!/usr/local/bin/perl print ("17 ARTI 26 SONUCU KACTIR.?\n"); $dogru_cevap = 43; # Doğru cevap atandı $girilen_deger = <STDIN>; chop ($girilen_deger); until ($girilen_deger == $dogru_cevap) { print ("Yanlis! Yeniden dene!\n"); $girilen_deger = <STDIN>; chop ($girilen_deger); } print ("Bravo..Dogru cevap!!!\n"); Çalışması : >untilprg >17 ARTI 26 SONUCU KACTIR.? >39 >Yanlis! Yeniden dene! >43 > Bravo..Dogru cevap!!! > OPERATÖRLER Aritmetik Operatörler: Daha evvel temel operatörleri görmüştük. (Toplama:+, Çıkarma:-, Çarpma:*, Bölme:/) Şimdi ise üs alma ,mod (artık) ve unary operatörlerini görelim. Üs alma için ** ,mod için % ,unary negation için - operatörü kullanılır. Örnek: $x = 2 ** 4 $y = 2 ** 2 $x = 2 ** $y; # 2x2x2x2 anlamındadır ..sonuçta $x içeriği 16 dır. # $y içine 4 atanır. # $x içine 2**4 yani 16 atanır. Örnek program : Program Adı usprg.pl olsun #!/usr/local/bin/perl #program 2 rakamının girdiginiz deger olarak üssünü bulur print ("Kullanacaginiz üs degerini giriniz:\n"); $us = <STDIN>; chop ($us); print ("2 nin $us .üssü = ", 2 ** $us, "\n"); Çalışması : >usprg.pl >Kullanacaginiz üs degerini giriniz: >16 >2 nin 16 .üssü = ", 65536 > NOT : Negatif ve noktalı sayı kullanmak hataya sebep olur Ör: (-5) ** 2.5 ..gibi Yine sınırları aşan sayılar da hataya neden olur Ör: 10 ** 999999 ..gibi MOD (Artık) Operatörü: Ör: $x = 25 % 4; Bu örnekte 25,4'e bölünür kalan(artık) 1’dir. Dolayısıyla $x 'in değeri 1’dir. İnteger olmayanlar integer'a(Tamsayı) dönüştürülür. Ör: $x = 24.77 % 4.21; Bu örnekte 24, 4'e bölünür kalan olmadığından $x değeri 0 dır. MOD işlemlerinde % işaretinin sağında 0 olamaz çünkü sıfıra bölme imkansızdır. Bu tür işlemler hata mesajı verir. Ör: $x = 25 % 0; $x = 25 % 0.1; Unary negation operatörü: - operatörü: Değeri -1 ile çarpmaktır. - işareti bu operatör ile kullanımında eksi işareti anlamında değildir. Örnek : - 5; # tamsayı -5' e esittir - $y; # $y * -1 anlamındadır. Ayrıca -operant (azaltma),+operant (arttırma), kullanım öncesi arttırma ++operand, kullanım öncesi eksiltme –operand kullanım sonrası arttırma operand++, kullanım sonrası elsiltme operand--, operatörleri de kullanılır. Örnek : # Normal yol: $Sayfano = 5; $Sayfano = $Sayfano + 1; print($Sayfano, "\n"); program çıktısı : 6 #Önceden arttırmalı yol: $Sayfano = 5; print(++$Sayfano, "\n"); program çıktısı : 6 Örnek : Önceden eksiltmeli opr kullanımı. $sayi = 5; $toplam = --$sayi + 5; print("$sayi $toplam \n"); Çıktı : 4 9 Örnek : sonradan arttırmalı opr kullanımı. $sayi = 5; $toplam = $sayi++; print("$sayi $toplam \n"); Çıktı : 6 5 KIYAS OPERATÖRLERİ KULLANIMI: $x = $a == $b; Yukarıdaki satırda $x in değeri, $a ve $b daki değerlerin durumuna bağlıdır. Şöyleki: eğer $a,$b ye eşitse, $a == $b eşitliği sonucu doğru değerini taşır(true) ve $x in değeri 0 OLMAZ. Sıfır olmayan değer taşır. eğer $a,$b ye eşit değilse, $a == $b eşitliği sonucu yanlış değerini taşır(false) ve $x in değeri 0 dır(Sıfır). Burada == operatörünün bir kıyas işlemi yaptığını görüyoruz. Kontrol ifadelerinde kıyas operatörleri sık sık kullanılır. örneğin; if ($a == $b) { print("$a eşittir $b\n"); } Perlde, kıyas operatörleri 2 sınıfta kullanılır. 1.Sayısal işlemlerde 2.String işlemlerde Tamsayı Kıyas Operatörleri: Operatör Açıklama < Küçük > Büyük == Eşit <= Küçük veya eşit >= Büyük veya eşit != Eşit değil <=> Kıyaslama dönüşü 1, 0, veya-1 Örnek : $a değişkeninde 5 varsa $a > 4 sonucu true (doğru) veya 0 olmayan değer $a > 7 sonucu false (yanlış) veya 0 dır. <=> operatörü özel bir durum arz eder. Aşağıdaki 3 değerden birini döndürür. 0, Kıyaslanan iki değer eşitse 1, ilk değer büyükse -1, ikinci değer büyükse String Operatörler String operatör Kıyas işlemi Sayısal opr.karşılığı lt Küçük < gt Büyük > eq Eşit == le Küçük veya eşit <= ge Büyük veya eşit >= ne Eşit değil != cmp Kıyas Dönüş 1, 0, or -1 <=> Örnekler : $result = "aaa" lt "bbb"; # Doğru $result = "aaa" gt "bbb"; # Yanlış $result = "aaa" eq "bbb"; # Yanlış $result = "aaa" le "aaa"; # Doğru $result = "aaa" ge "bbb"; # Yanlış $result = "aaa" ne "aaa"; # Yanlış $result = "aaa" cmp "bbb"; # -1 String - Sayısal Kıyas Karşılaştırması: Aşağıdaki örneklere bakalım. $sonuç = "123" < "45"; $sonuç = "123" lt "45"; # 123 ile 45 sayısal değer olarak kıyaslanır..sonuç yanlış(false) # 123 ile 45 alfabetik değer olarak kıyaslanır sonuç doğru(true). Floating-Point Sayılarda Kıyaslama: Bu sayılarda dikkat edilecek şey ondalık sonrasının net olmasıdır. Yuvarlanan sayı olursa sonuç hatalı çıkar. Ne demek istediğim aşağıdaki örnekten anlaşılacaktır. #!/usr/local/bin/perl $sayi1 = 14.3; $sayi2 = 100 + 14.3 - 100; print("sayi 1 : $sayi1, sayi 2 : $sayi2\n"); if ($sayi1 == $sayi2) { print("sayi 1,sayi 2 ye eşittir\n"); } else { print("sayi 1,sayi 2 ye eşit degildir\n"); } Çıktı: sayi 1 : 14.300000000000001, sayi 2 : 14.299999999999997 sayı 1, sayı 2 ye eşit değildir Mantıksal Operatörler && || ! değil $a || $b $a && $b ! $a ve veya # ikisinden biri 0 olmayan değerse doğru # sadece her ikiside 0 olmayan değerse doğru # $a,0 ise doğru Şu kullanım da doğrudur: $a or $b $a and $b not $a $a xor $b # # # # veya ve değil özel veya(birisi 0 olmayan değerse doğru,her ikisi ise değil) Örnekler: $a = 5; $b = 0; $a || $b; # true: $a, 0 değil $b || $a; # true $a && $b; # false: $b 0 ! $a; # false: $a ,0 değil,dolayısıyla ! $a 0 dır. ! $b; # true: $b 0 dır dolayısıyla ! $b ,0 değildir Bu operatörleri kontrol ifadelerinde bolca kullanırız Ör : if ($a1 == 26) { if ($b2 > 0) { if ($c1 eq "tamam") { print("Koşullar tamam!\n"); } } } Bu kodlamayı şu şekilde de yapabiliriz: if ($a == 26 && $b > 0 && $c eq "tamam") { print("3 koşulda tamam!\n"); } Her ikisinin sonuçları da aynıdır. $x == 0 || $y / $x > 5 Mantıksal operatörler ve alt ifadeler : Ör : $myval = $a || $b || $c; aşağıdaki ifadeyle aynıdır. if ($a != 0) { $deger = $a; } elsif ($b != 0) { $deger = $b; } else { $deger = $c; } Örnek : $deger = $a && $b && $c; ifadesi aşağıdakiyle aynıdır. if ($a == 0) { $deger = $a; } elsif ($b == 0) { $deger = $b; } else { $deger = $c; } ATAMA OPERATÖRLERİ Temel atama operatörü = göstergesidir. $a = 5; # 5 değeri $a değişkenin içine yerleştirilir. ATAMA operatörleri Operator İzah var = op1; op1,var 'a atanır(op1 değeri var içine yerleşir). var += op1; var + op1 ,var'a atanır. var -= op1; var - op1 ,var'a atanır. var *= op1; var * op1 ,var'a atanır. var /= op1; var / op1 ,var'a atanır. var %= op1; var % op1 ,var'a atanır. var .= op1; var. op1 ,var'a atanır. var **= op1; var ** op1 ,var'a atanır. var x= op1; var x op1 ,var'a atanır. var <<= op1; var << op1 ,var'a atanır. var >>= op1; var >> op1 ,var'a atanır. var &= op1; var & op1 ,var'a atanır. var |= op1; var | op1 ,var'a atanır. var ||= op1; var || op1 ,var'a atanır. var ^= op1; var ^ op1 ,var'a atanır. Örnekler : $result = 42; # $result 'un değeri 42 olur $value1 = $value2 = "a string"; # Hem $value1,hem de $value2 nin #içine "a string" atanır. $var = $var + 1; ile $var += 1; aynı işlemi ifade eder. ($var değişkeninin değeri 1 arttırılır ve yeni değer tekrar $var'a konur) Atama işlemleri örnekleri içeren bir tablo: İfade kullanımı Yürütülen işlem tablosu $a = 1; 1,$a içine yerleşir $a -= 1; $a = $a - 1; $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; $a ^= 2; $a = $a ^ 2; Alt ifadelerle Kullanım : Ör: ($a = $b) += 3; bu örnekte işleyiş şöyledir. Önce parantez içi işlenir. Bu durumda $a = $b; ve $a += 3; işlemleri yapılır. Otomatik Arttırma ve eksiltme: $a = $a + 1; $a += 1; Her iki örnekte de $a değeri 1 artırılmaktadır. $a değerini otomatik arttırma kullanımı ise şöyledir $a++; veya ++$a; 1. ve 2. ifadedeki fark şudur. 1.de arttırma işlemi atama işleminden önce 2. de sonra yapılmasını belirler. Otomatik eksiltmede buna benzer.Aynı mantıkla çalışır. Sadece işlem eksiltme şeklinde gerçekleşir. Ör : $a--; veya --$a; Örnek program : Program adı preprg.pl olsun #!/usr/local/bin/perl $sayi = 0; while (++$sayi <= 5) { print("Deger: $sayi\n"); } print("Son !\n"); Çalışması : >preprg.pl Deger: 1 Deger: 2 Deger: 3 Deger: 4 Deger: 5 Son ! > Örnek program : Program adı preprg2.pl olsun #!/usr/local/bin/perl $sayi = 0; while ($sayi++ <= 5) { print(" Deger: $sayi\n"); } print("Son !\n"); Çalışması : >prepprg2.pl Deger: 1 Deger: 2 Deger: 3 Deger: 4 Deger: 5 Deger: 6 Son ! > Bu örneğin çalışmasını anlamak için şu tabloyu inceleyelim. İşlem yürütme tablosu $valueTest anında Sonuç $value sonra Testten 0 true (0 <= 5) 1 1 true (1 <= 5) 2 2 true (2 <= 5) 3 3 true (3 <= 5) 4 4 true (4 <= 5) 5 5 true (5 <= 5) 6 6 false (6 <= 5) 7 (while döngüsü çıkışı) STRiNGLERDE OTOMATİK ARTTIRMA: $string1 = "abc"; $string1++; Şu anda $string1 içindeki değer "abd" dir. NOT : Stringlerde otomatik eksiltme olmaz ($string1--). Böyle bir durumda string içindeki değer -1 olur. ----***-----$string1 = "aBC"; $string1++; Şu anda $string1 içindeki değer "aBD" dir. -----***-----$string1 = "abz"; $string1++; # $string1 içi "aca" dır. -----***----$string1 = "AGZZZ"; $string1++; # $string1 içi "AHAAA" dır. -----***----$string1 = "bc999"; $string1++; # $string1 içi "bd000" dır. -----***----- STRİNG BİRLEŞTİRME VE TEKRARLAMA: . x .= operatorü, string birleştirir . operatorü, string tekrarlar. operatorü, string birleştirir ve atama yapar. Birleştirme : $yenistring = "tas" . "kafa"; satırı sonucu olarak $newstring değişkeninin içeriği "taskafa" olur. . operatörü değişkenlerle de kullanılır. Ör : $string1 = "tas"; $string2 = "kafa"; $yenistring = $string1 . $string2; $yenistring değişkeninin içeriği " taskafa " olur. Tekrarlama: $yenistring = "t" x 5; $yenistring değişkeninin içeriği "ttttt" olur. x operatörü değişkenlerle de kullanılır. Ör: $string1 = "t"; $tekrar = 5; $yenistring = $string1 x $tekrar; $yenistring değişkeninin içeriği "ttttt" olur. NOT !!!! : x operatörü kullanırken x etrafında boşluk bulunmalıdır. $yeni = $eski x 5; #Doğru kullanım $yeni = $eskix 5; # Yanlış " $yeni = $eski x5; # Yanlış " BİRLEŞTİRME ve ATAMA: $a = "Ata"; $a .= "türk"; # $a nın değeri şimdi "Atatürk" dir. Aşağıdaki kullanımda aynı sonucu verir. $a = "Ata"; $a = $a . "türk"; Örnek Program : Program adı strcon.pl olsun #!/usr/local/bin/perl $sonuc = ""; print("Kelimeler giriniz çıkış için sadece enter basınız\n"); $gir = <STDIN>; chop ($gir); while ($gir ne "") { $sonuc .= $gir; $gir = <STDIN>; chop ($gir); } print ("Girilen kelimeler:\n"); print ("$sonuc \n"); Çalısması: >strcon.pl Kelimeler giriniz çıkış için sadece enter basınız ben sen o Girilen kelimeler: benseno > DİĞER OPERATÖRLER: , (virgül) operatörü; ifadeyi parçalara ayırır. Ör: $a1 += 1; $a2 = $a1; satırları virgül kullanımı ile şu şekilde kodlanır, $a1 += 1, $a2 = $a1; , operatörü atama işlemlerinde sıkça kullanılır, Ör: $val = 26; $result = (++$val, $val + 5); ilkönce ++$val işlenir çünki virgülden öncedir $val,27 olur. Sonra 5 eklenir 32 olur bu değer,$result 'e atanır. ŞART(Koşul) operatörleri: Bunlar ? ve : operatörleridir. Ör: $sonuc = $a == 0 ? 14 : 7; çalışmasını inceleyerek anlayalım; eğer $a == 0 ise , $sonuc değişkenine 14 atanır, değilse 7 atanır. Yani koşul doğru ise ? sonrası, yanlış ise : sonrası atanır., eğer bu işlemi if else ile yapmak isteseydik şöyle kodlayacaktık. if ($a == 0) { $sonuc = 14; } else { $sonuc = 7; } Bir de şunu inceleyelim; $kosul == 43 ? $a1 : $a2 = 14; Buradaki işleyiş ise şöyledir; Eğer $kosul içindeki değer 43 ise, $a1 'e 14 atanır. Değilse $a2'ye 14 atanır.. Örnek Program : program adı pwdprg.pl olsun #!/usr/local/bin/perl print ("Parola giriniz:\n"); $parola = "ertan"; $giris = <STDIN>; chop ($giris); $sonuc = $giris eq $parola ? "Dogru parola!\n" : "Yanlis parola.\n"; print ($sonuc); Çalışması: >pwdprg.pl Parola giriniz: abc Yanlis parola. > LİSTE ve DİZİLER Listeler: Listeler parantezlerle sınırlandırılmış skalar değerler dizisidir. Ör : (1, 5.3, "hello", 2) Bu listenin 4 elemanı vardır. 1 , 5.3 , hello , ve 2. Elemanı olmayan liste boş listedir Ör : () Ör : (17, 26 << 2) listesi 2 elemanlıdır. 17 ve 104. Ör : (17, $var1 + $var2) Bu örnekte 2 elemanlıdır. 17 ve $var1 ve $var2 toplamı. Aşağıdaki kullanımlar listeler için geçerli diğer örneklerdir. ("string", 24.3, " string2") ($cevap, "cevap $cevap") Liste elemanlarını Dizilere yerleştirme: Öncelikle dizilerin tanımını görelim. Dizi değişkeni tanımı için o değişkenin başına @ karakteri konur. Geçerli Adlandırma Örnekleri: @my_array @list2 @uzun_isim_de_ kullanılabilir Geçerli olmayan adlandırma Örnekleri: @1dizi # rakamla başlayamaz @_dizi # alt-tire ile başlayamaz @a.son.dizi # . kullanılamaz Aşağıdaki örneği inceleyelim $deger = 1; @deger = (11, 27.1, "bir string"); Burada var isimli değişkenler tamamen farklı değişkenlerdir. $var skalar değişken olup,@var ise dizi değişkenidir. Aşağıdaki örnekte, @array bir dizidir ve sırasıyla elemanlarına 1,2,ve 3 atanmıştır. @array = (1, 2, 3); Dizi elemanlarına erişim: Erişim için o elemanın indisi(numarası) verilir. Ör: $var = @array[0]; burada @array dizisinin 1.elemanının indis'i verilerek(Dizilerde ilk eleman numarası 0 dır) o elemanın değerine ulaşılıyor ve değer $var değişkenine atanıyor. Dizilerde @array[0], 1.elemanı @array[1], 2.elemanı @array[2], 3.elemanı temsil eder ve sıralama bu şekilde devam eder. Örnek: @array = (1, 2, 3, 4); yukarda @array elemanlarına, liste elemanlarının atanmasını görüyoruz. dizi elemanları şu değerleri taşır: @array[0], değeri 1 @array[1], değeri 2 @array[2], değeri 3 @array[3], değeri 4 Bu aşamada aşağıdaki atamayı yapalım. $array[3] = 5; Şimdi dizi elemanları dizilişi şu şekildedir; @array[0], @array[1], @array[2], @array[3], yani (1, 2, 3, 5). değeri 1 değeri 2 değeri 3 değeri 5 Eğer olmayan dizi elemanı atanmak istenirse veya negatif (-) değer verilirse atanacağı değişken değeri null stringidir ki 0 a eşittir. Ör: @array = (1, 2, 3, 4); $skalar = $array[4]; dizide 5.eleman yani $array[4] yoktur dolayısıyla $skalar değeri null ("") dir. benzer şekilde $skalar = $array[-1]; sonucu da aynıdır. Bir de şu örneği inceleyelim. @array = (1, 2, 3, 4); $array[6] = 17; Dizinin görünümü şu şekildedir, (1, 2, 3, 4, "", "", 17) İndis olarak değişken de kullanılır, Ör: $index = 1; $skalar = $array[$index]; gibi... Dizi elemanlarına erişimde dizi değişkeninin başında $ olduğuna dikkatinizi çekerim. Çünkü dizinin her bir elemanı skalar değişken olarak işlem görür. Ör: $sebze[0] doğru @sebze[0] ise yanlış kullanımdır. Örnek program: Program adı dizprg.pl olsun #!/usr/local/bin/perl @dizi = (1, "tavuk", 1.23, "\"Tamam mi?\"", 9.33e+23); $say = 1; while ($count <= 5) { print ("$say . eleman @dizi[$say-1]\n"); $say++; } Çalısması : >dizprg.pl 1 . eleman 1 2 . eleman tavuk 3 . eleman 1.23 4 . eleman "Tamam mi?" 5 . eleman 9.3300000000000005+e23 > Örnek program: program adı randiz.pl # rand() fonksiyonu ile 1- 10 arası random sayı üreten program #!/usr/local/bin/perl $say = 1; while ($say <= 100) { $randnum = int( rand(10) ) + 1; $randtoplam[$randnum] += 1; $say++; } # Herbir sayı için toplamı yaz $say = 1; print ("Herbir sayı için toplam:\n"); while ($say <= 10) { print ("\tsayi $say: $randtoplam[$say]\n"); $say++; } Çalısması: >randiz.pl Herbir sayı için toplam: sayi 1: 11 sayi 2: 8 sayi 3: 13 sayi 4: 6 sayi 5: 10 sayi 6: 9 sayi 7: 12 sayi 8: 11 sayi 9: 11 sayi 10: 9 > LİSTE gösterimi: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) gösterimi ile (1..10) gösterimi aynıdır. (2, 5..7, 11) örneğinden anlaşılan ise şudur: listenin 5 elemanı vardır 2,5,6,7,11 String ifadeler içinde aynı kullanım geçerlidir Ör: ("aaa", "aab", "aac","aad") ifadesi şu şekilde de gösterilebilir. ("aaa".."aad"). Benzer şekilde; ("BCY", "BCZ", "BDA", "BDB") ifadesi ("BCY".."BDB"), ile aynıdır. @alphabet = ("a".."z"); ifadesi bir alfabe listesini gösterir. Örnek program: Program adı lstprg.pl olsun. #!/usr/local/bin/perl print ("Baslangic numarasini gir:\n"); $basla = <STDIN>; chop ($basla); print ("Bitis numarasini gir:\n"); $bitis = <STDIN>; chop ($bitis); @liste = ($basla..$bitis); $say = 0; print ("Liste yaziliyor:\n"); while ($liste[$say] != 0 || $liste[$say-1] == -1 || $liste[$say+1] == 1) #burada liste dizisinin sonu ve liste #elemanı icinde 0 var mı kontrolu yapılıyor { print ("$liste[$say]\n"); $say++; } Çalısması: >lstprg.pl Baslangic numarasini gir: -2 Bitis numarasini gir: 2 Liste yaziliyor -2 -1 0 1 2 > Örnek program : Program adı dizprg2.pl #!/usr/local/bin/perl @dizi1 = (14, "ekmek", 1.23, -7, "su"); @dizi2 = @dizi1; $say = 1; while ($say <= 5) { print("eleman $say: $array1[$say-1] "); print("$dizi2[$say-1]\n"); $say++; } Çalışması : >dizprg2.pl eleman 1: 14 14 eleman 2: ekmek ekmek eleman 3: 1.23 1.23 eleman 4: -7 -7 eleman 5: su su > Aşağıdaki kullanım şeklini inceleyelim. Ör : @liste1 = (2, 3, 4); @liste2 = (1, @liste1, 5); Sonuçta @liste2 dizisinin içeriği (içerdiği liste) şu şekildedir. (1,2,3,4,5) Örnek program : Program adı dizprg3.pl #!/usr/local/bin/perl @al = " asla "; @yaz = ("Ben", @al, "kaybetmem!\n"); print @yaz; Çalışması : >dizprg3.pl Ben asla kaybetmem! > Aşağıdaki parantez kullanımını inceleyiniz $ali = "Ali"; print (("Hey, " . $ali . "!\n") x 2); Bu kodlama sonucu çıktı şöyle olur; Hey, Ali! Hey, Ali! Dizilerde yerine koyma: Şu örneğe bakalım. @a = (1, 2, 3); print (@a, "\n"); Çıktı > 123 Burada bir problem var gibi... Bir de şuna bakın, @a = (1, 2, 3); print ("@a\n"); Çıktı > 123 Böyle olacaktı..farkı belirleyen kodlamayı inceleyin. LİSTENiN UZUNLUĞUNU ELDE ETME: @a = (1, 2, 3); $skalar = @a; Bu kodlama şekliyle biz @a dizisinin(oluşturan listenin) uzunluğunu elde ederiz. $skalar içindeki bu değer 3 tür. Not: $skalar = @a; ($skalar) = @a; yukarıdaki satırlar farklıdır. 1.satırda $skalar,@a dizisinin uzunluğunu tutar. 2.satırda $skalar,@a dizisinin ilk elemanını tutar. Dikkat ediniz... Dizilerle çalışmayı iyice anlamak için aşağıdaki programların kodlanışlarını iyi inceleyiniz. Örnek program : Program adı dizprg4.pl #!/usr/local/bin/perl @dizi = (14, "Peynir", 1.23, -7, "elma"); $sayi = 1; while ( $sayi <= @dizi) { print("eleman $sayi: @dizi[ $sayi-1]\n"); $sayi++; } Çalışması: >dizprg4.pl eleman 1: 14 eleman 2: Peynir eleman 3: 1.23 eleman 4: -7 eleman 5: elma > Alt dizilerin kullanımı: Örnek program : Program adı dizprg5.pl #!/usr/local/bin/perl @dizi = (1, 2, 3, 4); @altdizi = @dizi[1,2]; # dizinin 2 ve 3 .elemanından alt dizi olustu. # hatırlayınız...dizinin 1.elemanı indisi $dizi[0] dır. print ("Altdizinin 1.elemanı: $altdizi[0]\n"); print ("Altdizinin 1.elemanı: $altdizi[1]\n"); Çalışması: >dizprg5.pl Altdizinin 1.elemanı: 2 Altdizinin 2.elemanı: 3 > Örnek program : Program adı dizprg6.pl #!/usr/local/bin/perl @dizi = ("bir", "iki", "üç", "dört", "beş"); @sira = (1, 2, 3); @altdizi = @dizi[@sira]; print ("Dizi dilimi: @altdizi\n"); Çalışması : >dizprg6.pl Dizi dilimi: iki üç dört > DİZİ dilimlerine ATAMA: @a [0,1] = ("string", 46); bu örnekte @a dizisinin ilk 2 elemanı değeri string ve 46 olur. Ör : aşağıdaki satır sonucu @a [0..2] = ("string1", "string2"); 3.eleman null stringtir. Ör : Aşağıda ise listenin 4.elemanı diziye atanamaz(dikkate alınmaz). @a [0..2] = (1, 2, 3, 4); Örnek program : program adı dizprg7.pl #!/usr/local/bin/perl @dizi = ("a1", "a2", "a3", "a4"); @dizi[1,2] = ("b2", "b3"); print ("@dizi\n"); Çalışması: >dizprg7.pl a1 b2 b3 a4 > Örnek program: Program adı dizsort.pl #Okunan değerleri sıraladıktan sonra basan örnek #!/usr/local/bin/perl #giriş işlemi print ("Değerleri giriniz\n"); print ("çıkış için boş satır giriniz.\n"); $say = 1; $gir = <STDIN>; chop ($gir); while ($gir ne "") { @a [$say -1] = $gir; $say++; $gir = <STDIN>; chop ($gir); } # sıralama işlemi $say = 1; while ($say < @a) { $x = 1; while ($x < @a) { if ($a [$x - 1] gt $a [$x]) { @a [$x-1,$x] = @a [$x,$x-1]; } $x++; } $say++; } #basma işlemi print ("@a\n"); Çalışması: >dizsort.pl Değerleri giriniz çıkış için boş satır giriniz. fok bebek dil bal bal bebek dil fok > Standart giriş (klavye ) den dizi okuma: giriş dizi değişkenine yapılır. Ör: @a = <STDIN>; Örnek program : program adı dizkey.pl #!/usr/local/bin/perl @a = <STDIN>; print (@a); Çalışması: >dizkey.pl 1.satır 2.satır son satır. ^D > (control ve D tuşu) 1.satır 2.satır son satır. DİZİ KÜTÜPHANE FONKSİYONLARI: Dizilerde sıralama: Bu işlem için kullanılan fonksiyon sort() dur. Ör: liste = sort (array); Ör: @array = ("Bu", "bir", "test", "dir"); dizi bu şekilde oluştu. Şimdi sort ile sıralayalım; @array2 = sort (@array); sonuçta @array2 dizisi içeriği listesi şu şekildedir. ("bir", "bu", "dir", "test") @array dizisi içeriği ise değişmez...aynıdır.("Bu", "bir", "test", "dir") veriler alfabetik değilse; @a = (70, 100, 8); @a = sort (@a); o zaman sıralama şöyle gerçekleşir. (100, 70, 8) Dizi değişken veya listeleri ters sıraya sokma: Bu işlemi reverse() fonksiyonu yapar. Örnek: @a = ("bal", "incir", "arı", "sinek"); @a2 = reverse(@a); @a2 içeriği listesi şu şekildedir: ("sinek", "arı", "incir", "bal") Örnek program: program adı tersdiz.pl #program klavyeden girilen bilgileri ters olarak # (alfabetik olarakbuyukten kucuğe) sıralar #!/usr/local/bin/perl @input = <STDIN>;; @input = reverse (sort (@input)); print (@input); Çalışması : >tersdiz.pl fal bal dil bez ^D > fal dil bez bal DİZİLERDE chop() FONKSİYONU: chop() fonk.nun son karakteri sildiğini biliyoruz. Ör : $a = "Ala"; chop ($a); $var içeriği şu anda "Al" dır. Dizi listelerinde kullanımı: Ör: @list = ("Aslan", "12345", "Geyik"); chop (@list); Şu an @list içeriği liste şu şekildedir: ("Asla", "1234", "Geyi") Başka bir örnek: @a = <STDIN>; chop (@a); Bu şekilde klavyeden kullanımda yeni satır karakteri yok edilerek diziye alınır. STRİNG LİSTESİNDEN TEK STRİNG OLUŞTURMA: Bu görevi join() fonksiyonu yerine getirir. Ör: $string = join(" ", "bu", "bir", "liste", "dir"); $string içeriği şudur: "bu bir liste dir" join da ilk " " kısmı stringler arasında kullanılacak karakteri bildirir. Yukarda ki örnekte bu karakter boş stringtir. Aşağıdaki örneğe bakınca daha iyi anlayacaksınız. $string = join("::", "kelime", "ve", "sütun"); sonuçta oluşan $string stringinin içeriği şöyle görünür : "kelime::ve::sütun" Bir başka örnek: @liste = ("Bu", "bir"); $string = join(" ", @list, "stringdir"); $string içeriği : "Bu bir stringdir" olur. Örnek Program: program adı joprg.pl #!/usr/local/bin/perl @gir = <STDIN>; chop (@gir); $string = join(" ", @gir); print ("$string\n"); Çalışması: >joprg.pl Ben perl öğrenmeye basladım. ^D > Ben perl öğrenmeye basladım. STRİNGLERİ AYIRMA: split()fonksiyonu: join tersi işlev görür. stringler arası karakter iki adet / karakteri arasında belirtilir. $string = "bu::bir::ayırma::örneği"; @dizi = split(/::/, $string); sonuc olarak @dizi içeriği şu şekildedir: ("bu","bir","ayırma","örneği") bununla ilgili bir kelime sayma programını inceleyelim program adı kesay.pl olsun #!/usr/local/bin/perl $kelimesay = 0; $gir = <STDIN>; while ($gir ne "") { chop ($gir); @dizi = split(/ /, $gir); $kelimesay += @dizi; $gir = <STDIN>; } print ("Toplam kelime sayısı: $kelimesay \n"); Çalışması: >kesay.pl bu ilk satır bu da ikincisi son satır da bu olsun. ^D > Toplam kelime sayısı: 11 Şimdi de son öğrendiklerimizi içeren bir örnek : Klavyeden girilen kelimeleri ters sırada yerleştirip yazalım. Program adı fnk.pl #!/usr/local/bin/perl # Klavyeden girişini yap @giris = <STDIN>; chop (@giris); # Her bir satırdaki kelimeleri ters sırada yerleştir $satir = 1; while ($satir <= @giris) { @kelime = split(/ /, $giris[$satir -1]); @kelime = reverse(@kelime); $giris[$satir -1] = join(" ", @kelime, "\n"); $satir ++; } #şimdi onların sırasını ters cevir ve yazdır @giris = reverse(@giris); print (@giris); >fnk.pl bir iki üç dört beş altı. ^D altı. beş dört üç iki bir > DOSYA İŞLEMLERİ Dosya Açma: Biçimi : open (dosyadeğişkeni, dosyaadı); dosyadeğişkeni : Dosyanın basvuracağı, kullanmak istediğiniz isim. Herhangi bir harf,rakam ve _ karakterlerinden oluşur. İlk karakter harf olmalıdır. Aşağıdakiler geçerli adlardır. MY_NAME NAME2 A_REALLY_LONG_FILE_VARIABLE_NAME Aşağıdakiler ise geçerli değildir. 1NAME A.FILE.NAME _ANOTHERNAME if dosyaadı : Açılacak dosyanın makine içindeki yeri ve adı Örnek: open(FILE1, "file1"); burada işlem yapılacak dosya file1 dir. Ona başvuruyu temsil eden isim ise FILE1 dir. Perl file1' açacağını anlar ve onu FILE1 ile birleştirir. programda FILE1 adı kullanıldığında file1’ i temsil eder. Eğer değişik bir dizindeki file kullanılacaksa yolu tam verilmelidir. open(FILE1, "/home/ertan/rehber.dat"); gibi... Dosya Açılma biçimleri: Dosya kullanım amacına göre 3 şekilde açılır. 1.Okuma amacıyla 2.Yazma amacıyla 3.Ekleme Amacıyla 1.Okuma için açma modu : Var olan bir dosya okuma amaçlı açılır. Ör : open(READFILE, "/home/ertan/rehber.dat"); 2.Yazma için açma modu ( > ) : Mevcut olmayan,ilk defa oluşturulacak dosyalar bu mod ile açılır. Eğer mevcut bir dosya bu modda açılırsa içeriği tamamen silinir ve yeniden oluşur. Ör: open (OUTFILE, ">/home/ertan/rehber.dat"); 3.Ekleme için açma modu ( >> ) : Var olan bir dosya yazma(var olan kayıtlara ekleme) amacıyla açılır. Ör: open (APPENDFILE, ">>/home/ertan/rehber.dat"); Önemli Notlar: -Bu modlardan default olanı okuma modudur. -Bir dosya yazma modunda açılırsa içeriği tamamen silinir. -Aynı anda aynı dosyaya hem okuma hemde yazma işlemi yapamazsınız. -Ekleme moduyla açtığınızda sadece ekleme yapabilir ama o dosyadan o anda okuma yapamazsınız. -Eğer standart giriş (klavyeden dosyayayazılma) kullanılacaksa(<STDIN>;) <STDIN>; için açma (open) işlemi yapılmaz. Dosya Açma işleminin doğruluk kontrolü: Bu işlem için if, unless gibi deyim ve fonk.lar kullanılırak kontrol yapılır. Eğer hata varsa dönen değer 0 dır.Hata yoksa 0 olmayan eğer döner. Dosya test operatörlerini daha sonra işleyeceğiz. Örnek : if (open(DOSYAM, "/home/ertan/dosya")) { # file başarı ile açıldığında if bloğu içi # olan bu kısım işlenir } # dosya açılmamışsa burası işlenir. Dosyadan okuma biçimi : Dosyayı temsil eden ad <> karakterleri içersinde gösterilir. Ör: $kayit = <DOSYAM>; ...gibi Bu komutla DOSYAM ile temsil edilen dosyadan bir kayıt(satır) okunur ve $kayit skalar değişkenine atanır. ÖRNEK PROGRAM : Dosyadan kayıt okuyup ekrana basan program Adı dosya1.pl olsun.Kullanacağımız dosyanın adı bilgi.dat ve içeriğinin de, Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. şeklinde olduğunu varsayalım. #!/usr/local/bin/perl if (open(DOSYAM, "bilgi.dat")) { $kayit = <DOSYAM>; while ($kayit ne "") { print ($kayit); $kayit =<DOSYAM>; } } Çalışması : >dosya1.pl Bu ilk kayıttır. İkinci kayıt. > Dosyadaki son kayıt. die() FONKSİYONU ile PROGRAM SONLANDIRMA İŞLEMİ: Herhangi bir durumda programdan çıkış işlemi yapılacaksa die() fonksiyonunu kullanabiliriz. Bu fonksiyonun yazım formatı: die (mesaj); şeklindedir. Ör: die ("Program işleyişi durdu!\n"); komutu kullanılmışsa program aşağıdaki mesajla kesilir. Program işleyişi durdu! Şimdi Örnek bir programda bunu kullanalım program adı dosya2.pl programda yine bilgi.dat dosyası ile işlem yapalım... #!/usr/local/bin/perl unless (open(DOSYAM, "bilgi.dat")) { die ("bilgi.dat dosyası açılamadı!!!\n"); } # yukardaki unless bloğu yerine şu şekilde de kodlama yapabilirdik. # #open (DOSYAM, "bilgi.dat") || die ("bilgi.dat dosyası açılamadı!!!"); # # # Program akışı bu satıra geldiyse dosya açıldı demektir $kayit = <DOSYAM>; while ($kayit ne "") { print ($kayit); $kayit = <DOSYAM>; } Çalışması: >dosya2.pl Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. > Not : Eğer bilgi.dat dosyası yok veya bozuk olsaydı o zaman die ile başlayan satırları içeren blok devreye girer ve programın işleyişi, bilgi.dat dosyası açılamadı!!! mesajı ile kesilirdi. programda unless () fonksiyonu kullanıldığını da gördünüz. Ne işe yaradığını programı dikkatle incelerseniz anlayacaksınız. die fonksiyonu ile hangi satırda hata verdiğini de yazdırabiliriz. Sondaki \n karakterini kaldırmamız gerekir. Örnekleri inceleyerek kullanım farkı sonuçlarını anlayalım. die ("Dosya bulunamadı\n"); Çıktısı : Dosya bulunamadı die ("Dosya bulunamadı"); Çıktısı : Dosya bulunamadı at dosya2 line 14. Not : dosya2 programın adıdır.(program adı dosya2.pl ise). DOSYADAN dizilere OKUMA: Genel formatı: @array = <DOSYAM>; şeklindedir. Bunu örnek programda inceleyelim. Dosyanın tamamı bir diziye okunacak ve ekrana basılacaktır. Program adı dosya4.pl olsun ve bilgi.dat kullanılsın. #!/usr/local/bin/perl unless (open(DOSYAM, "bilgi.dat")) { die ("bilgi.dat dosyası açılamadı!!!\n"); } @okuyandizi = <DOSYAM>; #Bir üst satırda dosyanın tamamı dizi elemanları olarak diziye alınır #dizi listesi görünümü şu şekildedir #("Bu ilk kayıttır.\n" ....>burası $okuyandizi[0],yani dizinin ilk elemanı # "İkinci kayıt.\n" ....>burası $okuyandizi[1],yani dizinin ikinci elemanı # "Dosyadaki son kayıt.\n") ....>burası $okuyandizi[2],yani dizinin üçüncü elemanı # aşağıda ise ekrana basılır. print (@okuyandizi); Çalışması : >dosya4.pl Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. > DOSYALARA YAZMA İŞLEMİ : Dosya yazma amaçlı (yazma ve ekleme) açılır. Sonrada yazdırma komutu uygulanır. Örneğin; open(DOSYAM, ">bilgi.dat"); ile açılır print DOSYAM ("Bu ilk kayıttır.\n"); komutuylada satır yazılır. Yukarda ki kodlama sonucu bilgi.dat içeriği şöyledir ; Bu ilk kayıttır Bir örnek program yapalım. Program adı dosya5.pl olsun. İki dosya kullanalım veren.dat ve bilgi.dat. bilgi.dat'a yazılsın. veren.dat dosyası içeriği şöyle olsun; Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. #!/usr/local/bin/perl veren.dat'tan okutup unless (open(VEREN, "veren.dat")) { die ("veren.dat dosyası açılamadı!!!\n"); } unless (open(DOSYAM, ">bilgi.dat")) { die ("bilgi.dat dosyası açılamadı!!!\n"); } $kayit = <VEREN>; # veren.dat'tan bir satır,$kayit değişkenine aktarılır. while ($kayit ne "") { # veren.dat kayıtları bitti mi? Bittiyse blok dışına çık. print DOSYAM ($kayit); # $kayit değişkeninde ki satır bilgi.dat'a yazdırılır. $kayit = <VEREN>; # veren.dat'tan bir satır,$kayit değişkenine aktarılır. } print("Aktarma işlemi tamamlandı !!!"); # tırnak içindeki mesaj ekrana yazdırılır. Çalışması: >dosya5.pl Aktarma işlemi tamamlandı !!! Not: veren.dat dosyasının içeriği aynen bilgi.dat dosyasına aktarılır ve sonuçta her iki dosya içeriği de aşağıdaki görünümde olup aynıdır. Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. STANDART ÇIKTI DOSYASI: Standart çıktı dosyası tıpkı standart girdi dosyası gibi sistem fonksiyonudur. Standart girdi(<STDIN>;) klavyeden girişi temsil ediyordu. Standart çıktı aygıtı ise ekrandır. Standart çıktı aygıtına yazdırma işlevini <STDOUT>; komutu görür. Şu iki satırın işlevi aynıdır. print ("Here is a line of output.\n"); print STDOUT ("Here is a line of output.\n"); dolayısıyla print STDOUT... kullanımına gerek yoktur. Perl bu işi otomatikman yapar. DOSYA BİRLEŞTİRME :(merge) İki dosyadan okuttuğumuz satırlardan yeni bir dosya oluşturma: Bir çok değişik mantıkla yapılabilir. Mesela iki dosyadan okutulan satırları standart output (ekran) dosyasına yazan bir program. program adı dosya6.pl, okutulacak dosyalar dosya1 ve dosya2 olsun dosya1 kayıtları: a1 a2 a3 dosya2 kayıtları b1 b2 b3 ekrana (standart çıktı dosyasına) şu şekilde yazsın istiyoruz varsayalım, a1 b1 a2 b2 a3 b3 #!/usr/local/bin/perl open (DOSYA1, "ilk") || die ("ilk dosya açılamadı !\n"); open (DOSYA2, "ikinci") || die ("ikinci dosya açılamadı !\n"); $satir1 = <DOSYA1>; $satir2 = <DOSYA2>; while ($satir1 ne "" || $satir2 ne "") { if ($satir1 ne "") { print ($satir1); $satir1 = <DOSYA1>; } if ($satir2 ne "") { print ($satir2); $satir2 = <DOSYA2>; } } Çalışması: >dosya6.pl a1 b1 a2 b2 a3 b3 STANDART GİRİŞ ÇIKIŞ YÖNLENDİRMESİ: Bu işlevi >, < karakterleri sağlar. (Unix'teki gibi) Biliyoruz ki , $line = <>; komutu ile klavyeden bir satır girişi sağlanıyordu. Aynı komutu yazarak istenilen bir dosyadan nasıl giriş sağlayabiliriz. Şöyle; programadı < girisdosya > çıktıdosyaı komutu girildiğinde giriş için değerler girisdosya dosyasından alır ve çıktıyıda print ($line); komutuyla çıktıdosya dosyasına yazar. STANDART HATA DOSYASI: Buda hazır bir değişken kullanılarak halledilmiştir. Standart hata dosyası <STDERR>; dir ve ekranı temsil eder. Ekrana çıkmasını istemezsek başka bir dosyaya yönlendirme ile gönderebiliriz. Örnek program : Standart hata(error) kullanımlı program. dosya adı dosya7.pl olsun #!/usr/local/bin/perl open(DOSYAM, "bilgi.dat") || die ("bilgi.dat dosyası açılamadı!!!\n"); print STDERR ("bilgi.dat dosyası başarıyla açıldı !!!.\n"); $kayit = <DOSYAM>; while ($kayit ne "") { chop ($kayit); print ("\U$$kayit\E\n"); # Büyük harfe çevirerek basar $line = <DOSYAM>; } Çalışması: (bilgi.dat dosyası mevcut varsayıyoruz) >dosya7.pl bilgi.dat dosyası başarıyla açıldı !!!. > Not : die () fonksiyonu çıktıyı standart output(çıktı) değil standart error(hata) dosyasına yollar. Bu demektir ki die() fonk.mesajları daima ekrana çıkar. DOSYA KAPATMA: Kullanımı sona eren dosyalar close fonk. ile kapatılır. Örnek: close (DOSYAM); # Dikkat ! close (bilgi.dat) değil. DOSYA STATÜSÜNÜ BELİRLEME - TEST OPERATÖRLERİ KULLANIMI: Statüye karar verme: Dosya işlemlerinde bir çok şeyi test etmeye ve dosya durumunu belirlemeye ihtiyacımız olabilir. Örneğin: Dosya mevcut mu? text dosyası mı? Okunabilir mi? Boş mu? v.b... Bunları belirlemek için kullanılan operatörler vardır. Ör : dosya test operatörü kullanımlı bir program. program adı dosya8.pl olsun.Açılmamış bir dosyanın varlığını test ediyor. #!/usr/local/bin/perl unless (open(DOSYAM, "bilgi.dat")) { if (-e "bilgi.dat") { # -e dosya test operatörüdür. # Dosya mevcut mu? test eder. die ("bilgi.dat dosyası mevcut ama açılamadı!!!.\n"); } else { die ("bilgi.dat dosyası mevcut değil!!!.\n"); } } $kayit = <DOSYAM>; while ($kayit ne "") { chop ($kayit); print ("\U$kayit\E\n"); $kayit = <DOSYAM>; } Çalışması: (varsayalım ki dosya mevcut olmasın) >dosya8.pl bilgi.dat dosyası mevcut değil!!! > Not : -e yanındaki ifadede değişken de kullanılabilir Ör: $var = "file1"; if (-e $var) .... veya $var = "file1"; if (-e $var . "a") gibi.. (burada file1a isimli dosya sözkonusu) perl, if (-e $var . "a") ifadesini . karakterinin(stringte birleştirme) önceliğinden dolayı karıştırmaz. string'te tam yol da belirtilebilir. Ör: if (-e "/u/ertan/bilgi.dat") ... gibi.... BAZI DOSYA TEST OPERATÖRLERİ Operatör İzah -d Dosya bir dizin mi? -e Dosya mevcut mu? -f Dosya normal (sıradan) dosya mı? -l Dosya sembolik link mi? -o Dosyanın sahibi kullanıcı mı? -r Dosya okunabilir dosya mı? -s Dosya boş olmayan dosya mı? -w Dosya yazılabilir dosya mı? -x Dosya çalıştırılabilir dosya mı? -z Dosya boş dosya mı? -B Dosya bınary dosya mı? -O Dosya sahibi sadece kendi gerçek kullanıcısı mı? -R Dosya sadece kendi gerçek kullanıcısı tarafından mı okunabilir? -S Dosya socket mi? -T Dosya text dosya mı? -W Dosya sadece kendi gerçek kullanıcısı tarafından mı yazılabilir? -X Dosya sadece kendi gerçek kullanıcısı tarafından mı çalıştırılabilir? gerçek kullanıcı:loginden girilen kullanıcı adı Örnek program: program adı dosya9.pl. Program yazma amaçlı bir dosya açarken mevcut mu kontrolü yapar. #!/usr/local/bin/perl unless (open(OKUNACAK_DOSYA, "okunandosya")) { die ("okunandosya adlı dosya açılamadı.\n"); } if (-e "yazilandosya") { die ("Halihazırda yazilandosya adlı bir dosya var.\n"); } unless (open(YAZILACAK_DOSYA, ">yazilandosya")) { die ("yazilandosya adlı dosya açılamadı.\n"); } $kayit = <OKUNACAK_DOSYA>; while ($kayit ne "") { chop ($kayit); } print YAZILACAK_DOSYA ("\U$kayit\E\n"); $kayit = <OKUNACAK_DOSYA>; Çalışması: >dosya9.pl Halihazırda yazilandosya adlı bir dosya var. > Not : Eğer yazilandosya olmasaydı,okunandosya kayıtları(satırları) yazılandosya adlı dosyaya Büyük harflere çevrilerek aktarılacaktı. Örnek program parçası : Dosya üzerinde okuma hakkı var mı? test eder. Program Adı dosya10.pl dosya.txt dosyasının varolduğunu ama okuma hakkı olmadığını varsayalım. #!/usr/local/bin/perl unless (open(DOSYAM, "dosya.txt")) { if (!(-e "dosya.txt")) { die ("dosya.txt isimli dosya bulunamadı.\n"); } elsif (!(-r "dosya.txt")) { die ("dosya.txt isimli dosyayı okuma hakkınız yok.\n"); } else { die ("dosya.txt açılamadı.\n"); } } Çalışması: >dosya10.pl dosya.txt isimli dosyayı okuma hakkınız yok. > Not : -r kullanımından önce -e operatörü testine gerek yoktur. Çünkü -r de dosyayı bulamasa yanlış (false) değeri döndürür. -r ve -e nin birlikte kullanım amacı tam olarak hatanın nerede olduğunun tesbiti olabilir. Örnek program : Dosya adı :dosya11.pl Dosyanın yazmak için açmadan önce boş olup olmadığını test eden program parçası Dosya var ve dolu olsun varsayalım. #!/usr/local/bin/perl if (-e "dosya.dat") { if (!(-w "dosya.dat")) { die (" dosya.dat dosyasına yazma hakkınız yok.\n"); } if (!(-z "dosya.dat")) { die ("dosya.dat dosyası boş değil.\n"); } } # Bu noktada dosya ya boş yada mevcut değildir ve yazma amaçlı açılabilir. >dosya11.pl dosya.dat dosyası boş değil. > Örnek Program: Bu program,-s operatörü kullanarak,standart giriş aracılığıyla dosya büyüklüğünü döndürür ve ekrana basar(yazar). Program adı dosya12.pl olsun. #!/usr/local/bin/perl print ("Dosya adını giriniz:\n"); $dosyaadi = <STDIN>; chop ($dosyaadi); if (!(-e $dosyaadi)) { print ("$dosyaadi adlı dosya mevcut değil.\n"); } else { $size = -s $dosyaadi; print ("$dosyaadi dosyası $size byte içeriyor.\n"); } Çalışması: >dosya12.pl > Dosya adını giriniz: bilgi.dat bilgi.dat dosyası 128 byte içeriyor. DOSYA DEĞİŞKENLERİYLE TEST OPERATÖRÜ KULLANIMI: Ör: Dosya değişkenimiz DOSYAM ise; if (-z DOSYAM) { print ("Bu dosya boş!\n"); } kodlaması ile DOSYAM ın temsil ettiği (mesela bilgi.dat) dosyanın durumu test edilir. DOSYA DİZİSİ OKUMA: Komut satırından verilen birden fazla dosya adı ile <,>,; karakterleri özelliklerini kullanarak birden çok dosya bilgilerine erişilebilir. Hatırlayacaksınız, $liste = <DOSYAM>; şeklindeki kullanım ile DOSYAM adlı dosyanın kayıtları $liste değişkenine alınıyordu.Pekala birden fazla dosyayı nasıl okutacağız? Varsayalım ki, Elimizde okutulacak 2 dosya var (daha fazla da olabilir) ve adları ise alan.dat ve bilgi.dat Kodlayacağımız programımızın adı da program.pl olsun. önce komut satırından şu komutu gireriz: > program alan.dat bilgi.dat ve enter tuşuna basarız bundan sonra program satırları içinde şu şekilde bir kodlama gerekir ki 3 dosyayı da arka arkaya kullanabilelim. $liste = <>; ( $liste = <DOSYAM>; kullanımını hatırlayın ve farkı görün) işte bu satır sayesinde her bir dosyanın işi bitince diğeri devreye girer. Yukarda ki izahlardan sonra daha iyi anlamak için bir program yazalım ve çalıştırıp işleyişi görelim. Ekrandan adı girilen 2 dosyanın (alan.dat ve bilgi.dat olsun)içeriğini ekrana basan program. Not : alan.dat ve bilgi.dat dosyaları içeriği aynıdır ve kayıtları şunlardır: Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt ve kodladığımız programın adı dosya13.pl olsun. #!/usr/local/bin/perl while ($gir = <>;) { # sıradaki dosyadan,sıradaki satır alınıp $gir 'e atanıyor print ($gir); # ve değişken içeriği yazdırılıyor(Son dosyanın sonuna kadar devam eder) } Çalışması: >dosya13.pl alan.dat bilgi.dat Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. Bu ilk kayıttır. İkinci kayıt. Dosyadaki son kayıt. > Not: dosya13.pl komutunu girerken dosya adlarını yazmasaydık standart input(<STDIN>) tan giriş beklerdi. Ek Not -1-: Dosya adı DOSYAM ise, <DOSYAM> kullanımını hatırlayalım. Skalar değişken kullanarak skalar değişken içeriği ne ise dosya adı olarak onu kullansın İstiyorsak; $dosyaadi = "DOSYAM"; $kayit = <$dosyaadi>; kodlamasını kullanırız. $dosyaadi değişirse okunacak dosyada değişmiş olur. Ek Not -2-: Unix' ten hatırlatma $ cp *.pl /u/ertan komutu dizindeki .pl uzantılı ne kadar dosya varsa /u/ertan <DIR>'na kopyalar. İşte <> nin, cp komutunun burada birden çok dosyayı elde edip kopyalaması mantığına benzeyen Bir kullanımı vardır. Örneğin; @dosyalistesi = <*.pl>; kodlaması *.pl olan tüm dosyaları @dosyalistesi dizisine listeler.Döngüde de kullanılabilir. Örneğin; while ($kayit = <*.pl>) { print ("$kayit\n"); } tüm dosyalar (uzantısı .pl olan) arka arkaya listelenir. DİZİLERE OKUTMA: Değişkenlere okutma gibidir.Biraz evvel gördüklerimiz uygulanabilir. Tek farkla ki okutulan değişken skalar değişken değil dizi değişkenidir. $liste = <DOSYAM>; yerine @liste = <DOSYAM>; kullanırız. Bu okutma işleminde dikkatinizi çekmek istediğim önemli bir nokta vardır. Şöyle ki; Bir dosyadan ,Skalar değişkene tek kayıt okunurken( $liste = <DOSYAM>; veya $gir = <>; gibi), dizi değişkenine tum dosya aktarılır( @liste = <DOSYAM>; veya @gir = <>; gibi). KOMUT SATIRI ARGÜMANLARINI DEĞER OLARAK GİRME(KULLANMA): Önceki programda, >dosya13.pl alan.dat bilgi.dat komutuyla alan.dat ve bilgi.dat'ı argüman olarak kullanmıştık. Perl bu argümanları değer olarak kullanan hazır bir dizi değişkeni sunar: @ARGV. Elde edilen argümanlar bu dizide dizi elemanlarını içeren bir liste olarak saklanır ve nasıl işimize yarayacaksa o amaca uygun kullanılabilirler. Örneğimizden yola çıkarsak, >dosya13.pl alan.dat bilgi.dat kullanımıyla, @ARGV dizisi içeriği ("alan.dat","bilgi.dat") listesi olarak set edilir. Burada $ARGV[0] içeriği "alan.dat",$ARGV[1] içeriği ise "bilgi.dat",dır. @ARGV elemanlari tıpkı diğer dizi değişkenleri gibi karşılıklı atama işlemlerinde kullanılabilirler. Örneğin, $var = $ARGV[0]; $ARGV[0] = 43; ...gibi... Argüman sayısını elde etmek istersek @ARGV dizisini bir skalar değişkene atarız. $arg_sayisi = @ARGV; $arg_sayisi skalar değişkenindeki değer argüman sayısını verir. Örnek Program : Bu program kelime arar ve sayar. Program adı: dosya14.pl olsun. Programı çalıştırırken alan.dat ve bilgi.dat dosyalarının adlarını ve bu dosyalarda aratacağımız "Bu" kelimesini komut satırından gireceğiz. #!/usr/local/bin/perl print ("Aranan Kelime: $ARGV[0]\n"); # ekrandan girdiğimiz Bu kelimesini ekrana yazar. $dosyasayisi = 1; $toplamkelimesayisi = 0; while ($dosyasayisi <= @ARGV-1) { unless (open (OKUNAN, $ARGV[$dosyasayisi])) { die ("$ARGV[$dosyasayisi] açılamadı\n"); } $kelimesayisi = 0; while ($kayit =<OKUNAN>;) { chop ($kayit); @kelimelerdizisi = split(/ /, $kayit); $w = 1; while ($w <= @kelimelerdizisi) { if ($kelimelerdizisi[$w-1] eq $ARGV[0]) { $kelimesayisi += 1; } $w++; } } print ("$ARGV[$dosyasayisi] içinde bulunan : "); print ("$kelimesayisi\n"); $dosyasayisi++; $toplamkelimesayisi += $kelimesayisi; } print ("Toplam : $toplamkelimesayisi\n"); Çalışması : >dosya14.pl Bu alan.dat bilgi.dat Aranan Kelime: Bu alan.dat içinde bulunan:1 bilgi.dat içinde bulunan:1 Toplam : 2 ARGV ve <> Operatörü: Gerçekte Perl de, <>; operatörü @ARGV dizisine bir referans (gönderme) içerir. <> görüldüğünde ilk file açılır ve adı $ARGV[0] içine atanır. Bu arada @ARGV içindeki ilk eleman silinir ve sonraki eleman bu ilk elemanın içine yerleşir (kaydırma işlemi- Bunu hazır shift(@ARGV) fonk.yapar;) Örnek Program: <> kullanılan kelime arama ve sayma programı.Adı dosya15.pl #!/usr/local/bin/perl $aranankelime = $ARGV[0]; print ("Aranacak kelime: $aranankelime\n"); shift (@ARGV); $toplamkelime = $kelimesay = 0; $filename = $ARGV[0]; while ($kayit = <>) { chop ($kayit); @kelimeler = split(/ /, $kayit); $w = 1; while ($w <= @kelimeler) { if ($kelimeler[$w-1] eq $aranankelime) { $kelimesay += 1; } $w++; } if (eof) { print ("$filename: içindede bulunan: "); print ("$kelimesay\n"); $toplamkelime += $kelimesay; $kelimesay = 0; $filename = $ARGV[0]; } } print ("Toplam : $toplamkelime\n"); Çalışması : >dosya15.pl Bu alan.dat bilgi.dat Aranan Kelime: Bu alan.dat içinde bulunan:1 bilgi.dat içinde bulunan:1 Toplam : 2 > LINK (HAT) AÇMA: --pipe-Unixte 2 ayri işlemi likleme(piping) işlemi ile birleştirebiliyorduk. Bu işlem için | (pipe) karakteri kullanılıyordu. Bu özelliği perl de kullanır. örneğin aşağıdaki komutla, open (MYPIPE, "| cat >hello"); MYPIPE açıldığında çıktı MYPIPE 'a gönderilir ve girdi cat >hello komutu olur. Aşağıda sistemdeki bir kullanıcıya perl programından mesaj gönderme örneği var.İncelersek daha iyi anlarız. open (MESAJ, "| mail ertan"); print MESAJ ("Merhaba Ertan! Bu mesaj perl den mail gönderme denemesidir!\n"); close (MESAJ); Bu satırlarda İlkönce open komutuyla MESAJ dosya değişkeniyle , -mail ertan- komutuna bağlantı kurulur. Daha sonra MESAJ adlı dosya değişkeni içeriği olan yazılan mesaj bu hat(bağlantı) ile ilişkilendirilir ve close komutu ile mesajı içeren satır ertan isimli kullanıcıya gönderilir. giden mesajın içeriği: Merhaba Ertan! Bu mesaj perl den mail gönderme denemesidir! olarak karşı taraftan okunacaktır. Pattern (string / kelime ) Örneği Bulma:(Pattern Matching) Bilhassa dosyalarda tarama yaparken çok kullanılan bu işlemin kurallarını öğreneceğiz. Pattern nedir ? : slash (/) karakterleri arasında bulunan karakter dizisidir. Ör: /gazi/ Bu pattern gazi kelimesini temsil eder. Pattern tarandığı bir satırda bulunduğunda uygun örnek bulunmuş olur. Biz şu ana kadar pattern bulma ile ilgili olarak @array = split(/ /, $line); benzeri örnekler gördük. Burada / / boşluk karakterini temsil ediyor ve o amaçla aranıyordu. Pattern bulmada kullanılan operatörler: Bir karakter stringinde pattern parçası bulmak için özel operatörler vardır. patternin varlığını test eden operatör =~ operatörüdür. Ör: $sonuc = $degisken =~ /abc/; Bu komutla $degisken içinde(stringte) abc patterninin bulunduğu test edilir. Sonuç $sonuç değişkenine atanır. Sonuç ise aşağıdakilerden biridir: 1- 0 olmayan değer veya true (doğru) --- pattern stringte bulundu ise --2- 0 veya false --- pattern stringte bulunmadıysa --1.sonucta $sonuc içeriği 0 olmayan bir değer,2.sonucta ise 0 değeridir. !~ operatorü, =~, operatörüne benzer tek farkla ki bu operatör patternin bulunmadığını (olumsuz karşılaştırma) test eder. Ör: $sonuc = $degisken !~ /abc/; Burada abc bulunmuşsa $sonuc değeri 0 dır.Bu tip kodlamalar özellikle şart ifadelerinde çok kullanılır. Örnek program : Program adı pat1.pl #!/usr/local/bin/perl print ("Icinde Lutfen kelimesi olan bir soru cümlesi giriniz:\n"); $soruyual = ; if ($soruyual =~ /lutfen/) { print ("Istenilen kelimeyi girdiniz.Teşekkür ederim!!\n"); } else { print ("Istenilen kelimeyi neden girmediniz?.\n"); } Çalışması: >pat1.pl Icinde Lutfen kelimesi olan bir soru cümlesi giriniz: Lutfen kapıyı açarmısınız? Istenilen kelimeyi girdiniz.Teşekkür ederim! > PATTERNLERDE ÖZEL KARAKTERLER + KARAKTERLERİ KULLANIMI önündeki(sol) karakterden 1 veya fazlası anlamındadır. ör: /de+f/ patterni aşağıdakilerinden herhangi birini bulur. def deef deeef deeeeeeef Not : + karakteri mumkun olduğunca önündeki karakterden 1 den fazla olanı bulur. Ör : /ab+/ ,abbc stringini taradığında, bulduğu örnek abb dir ab değil. + kullanımı özellikle bir satırı kelimelere bölme gibi işlemlerde çok kullanışlıdır. Örneğin bir satırda kelime aralarında bir veya birden fazla boşluk varsa ve bu boşluklardan kelime ayırımı yapacaksak + karakteri kullanımı çok uygundur. Ör : Girilen satırdaki kelimeleri sayan program yazalım. Satır girişi anında kelime aralarında 1 den fazla da boşluk bırakarak sonucu görelim. Program adı pat2.pl olsun. #!/usr/local/bin/perl $kelimesayisi = 0; $satir = <STDIN>; while ($satir ne "") { chop ($satir); @kelimeler = split(/ +/, $satir); $kelimesayisi += @kelimeler; $satir = <STDIN>; } print ("Toplam kelime sayısı: $kelimesayisi\n"); Çalışması: >pat2.pl Bu bir satır. Bu başka bir satır. Bu da son satır olsun. ^D > Toplam kelime sayısı: 12 [] KARAKTERİ KULLANIMI Bu karakter bir alternatif gruptan bir karakteri tanımlamak için kullanılır. Ör: /d[aA]f/ patterni daf ve dAf örneklerini bulur. Bu kullanımda pattern içeriği daha fazla da olabilir. Ör:/a[0123456789]e/ gibi.. Bu pattern a ile başlayan,onu takip eden bir rakam ve son karakter olarak e ile sonlanan örnekleri bulur. Daha evvel öğrendiğimiz + karakterini de [] karakteri ile birlikte kullanabiliriz. Ör: /a[cC]+f/ Bu pattern a ile başlayan,son karakteri f olan ve arada da bir veya birden fazla c ve C karakterleri olan örnekleri bulur. Ör; acf aCf accf aCcf aCcCcf Örnek Program : Adı pat3.pl. Önceki programda boşluk ve tab karakterini de düzenleyecek bir uygulama (kelimeler arsında bir veya fazla boşluk ve tab kullanılabilir). #!/usr/local/bin/perl $kelimesayisi = 0; $satir = <STDIN>; while ($satir ne "") { chop ($satir); @kelimeler = split(/[\t ]+/, $satir); $kelimesayisi += @kelimeler; $satir = <STDIN>; } print ("Toplam kelime sayısı: $kelimesayisi\n"); Çalışması: >pat3.pl Bu bir satır. Bu başka bir satır. Bu da son satır ^D > Toplam kelime sayısı: 12 olsun. Bu örnekte bir öncekinden tek bir fark vardır split(/[\t ]+/, $satir); kodlaması. Bu kodlama ile $satir değişkeninde bulunan ekrandan girdiğimiz satırda eğer kelimeler arasında bir veya birden fazla boşluk veya tab varsa bunların tümünü kelime ayıraç karakteri say ve öyle değerlendir komutu vermiş oluyoruz. * KARAKTERİ KULLANIMI * karakteri önündeki karakterden bir veya fazla olduğunda veya hiç olmadığında geçerli örneği bulur. Örneğin, /de*f/ paterni aşağıdaki örnekleri elde eder. df (ilk karakter -d-, son karakter -f-,arada -e- yok) def (ilk karakter -d-, son karakter -f-,arada 1 tane -e- var) deef (ilk karakter -d-, son karakter -f-,arada 1 den fazla -e- var) v.b... Bu karakter,[] karakteriylede kullanılır. Ör:/[eE]*/ gibi ..Bu pattern ile boş string ve e ile E karakterleri karışımı örnekler elde edilir. ? KARAKTERİ KULLANIMI ? karakteri önündeki karakterden bir tane veya hiç olmadığında geçerli örneği bulur. Örneğin patternimiz şu ise, /de?f/ bu patternin elde edeceği örnekler, df ve def tir.Dikkat ediniz deef,uygun örnek değildir çünkü, ? karakteri 1 taneden fazla karakteri kabul etmez. BU TİP ÖZEL KARAKTERLER İÇİN ESCAPE DİZİSİ KULLANIMI Perlde bulunan ve işlevi olan bazı karakterler ($,^,\, ..v.b.) pattern içinde nasıl kullanılır? Görelim. Bu karakterleri kendi özellikleriyle kullanmak için pattern içinde önlerine bir \ karakteri konur veya \Q \E karakterleri arasında kullanılır. mesela /\\+/ patterni stringte tüm \ karakteri (1 veya daha fazla) örneği olup olmadığını test eder. /\$/ $ karakterini, /\Q^ab*/ patterni, ^ab* karakterlerini, /\Q^ab\E*/ patterni ise,^a ile bunu takiben b karakterini test eder.(yani ^a dan sonra b olan ve b olmayanlar(* dan dolayı-hatırlayınız- doğru örneklerdir). HERHANGİBİR KARAKTER VE SAYI ÖRNEĞİ BULMA /a[0123456789]c/ Bu pattern ilk karakteri a son karakteri c olan ve aralarındaki karakterde 0 ile 9 arası herhangi bir rakam olan örnekleri test eder.Bu pattern daha kısa olarak şöyle de yazılabilir; /a[0-9]c/ aynı işlevi görürler. Örneğin a1c,a5c,a9c doğru örneklerdir. Benzer şekilde ( 0-9 kullanımı) küçük ve büyük harflerde test edilebilirler. Ör: /[a-z][A-Z]/, /[A-Z][A-Z]/, /[a-z][a-z]/, gibi.. ve rakam ve harfler birarada da test edilebilirler. Ör: /[0-9a-zA-Z]/ gibi..([] arasındaki karakterlerden birisi varsa geçerlidir) Örnek program : Basit bir değişken adı sınama programı. Program adı pat4.pl olsun. #!/usr/local/bin/perl print ("Bir değişken adı giriniz:\n"); $degisken = <STDIN>; chop ($degisken); if ($degisken =~ /\$[A-Za-z][_0-9a-zA-Z]*/) # skalar değişken olması için # $ karakteri ile başlamalı,herhangi # bir harf ve _ karakteri veya # herhangibir harf veya rakam olmalı { print ("$degisken bir skalar değişkendir\n"); } elsif ($degisken =~ /@[A-Za-z][_0-9a-zA-Z]*/)# dizi değişkeni olması için # @ karakteri başlamalı,herhangi # bir harf ve _ karakteri veya # herhangibir harf veya rakam olmalı { print ("$degisken bir dizi değişkenidir\n"); ile } elsif ($degisken =~ /[A-Za-z][_0-9a-zA-Z]*/) # dosya değişkeni olması için # herhangi bir harf ile başlamalı, # sonra _ karakteri veya # herhangibir harf veya rakam olmalı { print ("$degisken bir dosya değişkenidir\n"); # Bu aşamada herhangibir değişken adı kuralına uymuyor demektir. } else { print (" $degisken değişken adı kurallarına uymuyor.\n"); } Çalışması : >pat4.pl Bir değişken adı giriniz: $soyad $soyad bir skalar değişkendir > TAM ÖRNEĞİ BULMA Yukardaki programda değişken adı olarak aşağıdakilerden $soyad ad$soyad $soyad#atla sonuçta /\$[a-zA-Z][_0-9a-zA-Z]*/ patterni $soyad'ı bulacaktır. Dolayısıyla istediğimizin tam gerçekleşmemiş olur. Çünkü doğru örnek sadece 1.si ($soyad) olmalıydı.Tam olarak $soyad'ı bulsun istersek;yani sadece bu örnekte değil genelde tam örnek bulunsun istersek;tam örnek bulma (Pattern Anchoring) karakterleri kullanırız. Bunlar; karakterleridir. ^ veya \A, Sadece string başından bul. $ veya \Z, Sadece string sonundan bul. \b, Kelime sınırlarında(Kelimenin başı veya sonu) bul \B Kelime içinde bul. Şimdi örneklerle daha iyi anlayacağız. /^def/ sadece stringin en baştan ilk 3 karakteri def olanı bul. /def$/ sadece stringin en sondaki 3 karakteri def olanı bul. /^def$/ sadece def stringini bul. Şimdi önceki programa (pat4.pl) daha iyi bir değişken adı test programı yazabiliriz. Program adı pat5.pl olsun. #!/usr/local/bin/perl print ("Bir değişken adı giriniz:\n"); $degisken = <STDIN>; chop ($degisken); if ($degisken =~ /^\$[A-Za-z][_0-9a-zA-Z]*$/) { print ("$degisken bir skalar değişkendir\n"); } elsif ($degisken =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) { print ("$degisken bir dizi değişkenidir\n"); } elsif ($degisken =~ /^[A-Za-z][_0-9a-zA-Z]*$/) { print ("$degisken bir dosya değişkenidir\n"); } else { print ("$degisken değişken adı kurallarına uymuyor.\n"); } Çalışması: >pat5.pl Bir değişken adı giriniz: 5$soyad 5$soyad değişken adı kurallarına uymuyor. > KELİME SINIRLARINDA (kelimenin başında veya sonunda) TAM ÖRNEK BULMA: \b Örnek: Kelimenin başında :/\bert/ ert örneğiyle başlayan kelimeleri bulur. Örneğin ert,ertan gibi kelimeleri bulur bertan bulunmaz. Kelimenin sonunda :/ert\b/ kelimenin sonunda ert örneği olanları bulur. Örneğin ert,mert kelimeleri bulunur ertan,bertan bulunmaz. Şu örnekte ise sadece ert kelimesi bulunur. /\bdef\b/ Pekala şöyle bir soru aklımıza gelebilir. kelimemiz $ertan olsaydı ,/\bert/ patterni ile bu ert kelimesi bulunurmuydu? -Evet. Çünki Enbaştaki $ karakteri stringin değişken olduğunu belirten karakter olup dikkate alınmazdı. KELİME İÇİNDE TAM ÖRNEK BULMA: \B Bunu anlamak için yine örneklere bakalım. /\Btan/ patterni, bulacağı örnek mesela ertan dır. tan kelimesinde test olumsuzdur. Benzer şekilde /tan\B/ patterninde taner kelimesi aranan örneğe uyar ve /\Btan\B/ pattern ine uyan örnekler mesela utanan,dartanyan olup. tan,ertan,taner uymaz. Bu karakterler (\b,\B) bize, bir kayıt(satır)dan ,split komutunu kullanmaksızın kelime arama imkanını, sağlar. Örnek Program : Bu kelimesini içeren satırların sayısını veren program.pat6.pl #!/usr/local/bin/perl $sayi = 0; print ("Satırları Giriniz !:\n"); $satir = <STDIN>; while ($satir ne "") { if ($satir =~ /\bBu\b/) { $sayi += 1; } $satir = <STDIN>; } print ("'Bu' kelimesi içeren satir adeti: $sayi\n"); Çalışması : >pat6.pl Satırları Giriniz !: Bu birinci satır. Bu ikinci satır. Bu üçüncü satır. Sondan önceki satır Son satır. ^D > 'Bu' kelimesi içeren satir adeti: 3 Bu örnekte bir satırda kaç adet Bu kelimesi olduğunu düşünmedik. Sadece Bu kelimesi var mı şeklinde test ettik.Bir satırda birden fazla Bu kelimesi geçiyor ve biz kaç adet Bu geçtiğini bulmak istersek şu şekilde kodlama yapabiliriz. if ($satir =~ /\bBu\b/) { @kelimeler_dizisi = split(/[\t ]+/, $satir); $say = 1; while ($say <= @kelimeler_dizisi) { if ($kelimeler_dizisi[$say-1] eq "Bu") { $adet += 1; # kac adet Bu olduğu burada tutulur. } $say++; } } veya daha kısa olarak şöyle de kodlayabiliriz. if ($satir =~ /\bBu\b/) { @kelimeler_dizisi = split(/\bBu\b/, $satir); $adet += @kelimeler_dizisi - 1; } Hatta if kullanımına hiç gerek yoktur. @kelimeler_dizisi = split(/\bBu\b/, $satir); $adet += @kelimeler_dizisi - 1; kodlaması yeterlidir. Çünkü satır otomatikman aranacaktır ve varsa Bu kelimesi yeni bir kelimeyi (dolayısıyla yeni bir dizi elemanını)başlatan ayraç olacaktır. Dolayısıyla diziler 0.elemandan başladığından dizi boyutunun 1 eksiği bulunan kelime adedini verecektir. NOT : Pattern leri bir değişken içinde saklayarak,testlerde bu değişkenleri de kullanabiliriz. Ör: $pattern = "[\\t ]+"; @kelimeler_dizisi = split(/$pattern/, $satir); .. gibi. Örnek Program : Program Adı pat7.pl.İki dosyamız olsun. Kullanacağımız dosyaların adları bilgi.dat ve alan.dat olup içeriği ise, Bu ilk kayıttır. İkinci kayit. Dosyadaki son kayit. şeklinde olsun. Bu dosyaların adlarını komutsatırından girip,bir string 'i(pattern) bu dosyalarda taratalım.Taranacak string "kayit" olsun. Program stringi bulduğu takdirde hangi dosyada ve hangi kayıtta (satırda) olduğunu ekrana bassın. #!/usr/local/bin/perl print ("Aranacak kelimeyi giriniz : "); $aranankelime = <STDIN>; chop ($aranankelime); $dosya_adi = $ARGV[0]; $satirno = $bulunansayisi = 0; while ($satir = <>) { $satirno += 1; if ($satir =~ /$aranankelime/) { print ("$dosya_adi, satir $satirno\n"); @kelimeler = split(/$aranankelime/, $satir); $bulunansayisi += @kelimeler - 1; } if (eof) { $satirno = 0; $dosya_adi = $ARGV[0]; } } if ($bulunansayisi == 0) { print ("String bulunamadı !!! \n"); } else { print ("Bulunan $aranankelime kelimesi sayısı: $bulunansayisi\n"); } Çalışması: >pat7.pl alan.dat bilgi.dat Aranacak kelimeyi giriniz : kayit alan.dat, satir 2 alan.dat, satir 3 bilgi.dat, satir 2 bilgi.dat, satir 3 Bulunan kayit kelimesi sayısı: 4 > HARİÇTE KALAN SEÇENEĞİ Daha önce görmüştük ki [] karakterleri içindekilerden birisi aranırdı. [ karakterinden sonra gelen ^ karakterinin([^) özel işlevi vardır ve kendisinden sonra gelen ve ] karakterine kadar olan karakterlerin haricindekileri bulma (tarama) işlevi görür. Örneğin, patternimiz /d[^eE]f/ ise, anlamı şudur; ilk karakteri d sonraki karakter e veya E dışındaki bir karakter ve son karakter f olan örnekleri bul. NOT: Hatırlayalım; ^ karakterinin kendisi yalın olarak patterne dahil edilecekse,yani taranacak string içinde mevcutsa \ ile kullanırız. Ör: /d[\^eE]f/ paterninin bulacağı örnekler mesela d^f, def, or dEf olacaktır. ESCAPE DÜZENİNDE KULLANILAN KARAKTER DİZİLERİ TABLOSU Daha evvel /a[1-3]c/ şeklinde kullanım örnekleri görmüştük. bu pattern de [1-3] şeklindeki kullanıma dikkatinizi çekiyorum. 1 ile 3 arası herhangi bir rakam anlamındaydı. Aynı mantıkla, /[0-9]/ ise 0 ile 9 arası bir rakam daha doğrusu herhangi bir rakam anlamındaydı. Şimdi inceleyeceğimiz konu buna benzer değişik bir kullanım şeklini öğrenmemizi sağlayacak. mesela /[0-9]/ yerine aynı işlevi gören /\d/ patterni kullanacağız. Önce bunları bir tablo halinde listeleyelim. ESCAPE DÜZENİ AÇIKLAMA KARAKTER DİZİSİ \d Herhangi bir rakam [0-9] \D Rakam olmayan karakter [^0-9] \w Herhangi bir kelime karakteri [_0-9a-zA-Z] \W Kelime karakteri olmayan [^_0-9a-zA-Z] \s White space(Tab,Boşluk,v.b.) [ \r\t\n\f] \S White space olmayan [^ \r\t\n\f] Bu durumda mesela /[\da-z]/ patterni rakam veya herhangibir küçük harfi test eder. Pattern lerde kullanılan bir başka özel karakter . (nokta) karakteridir. . karakteri pattern içinde herhangi bir karakteri temsil eder(yeni satır (\n) karakteri hariç). Örneğin, /d.f/ patterninin test edeceği örnek; önce d, sonra (\n olmayan) herhangi bir karakter ve f dir. def, d5f, d\tf gibi...... Nokta (.) karakteri sık sık da * karakteriyle kullanılır.örneğin, /d.*f/ patterninin bulacağı örnekler başta d sonda f içeren df arasında \n harici herhangibir karakter veya karakterler den oluşan stringtir.* birden fazla olabilir anlamındadır ve ayrıca aradaki karakter lerden en fazlasına sahip örneği bulur. Ör: pattern /k.*a/ ise test edilen uygun örnekler ise kara,kona,karga,karavana ise bulunan string karavana olacaktır. Perlde bulunacak örneklerdeki karakterleri istediğimiz buldurabiliriz(sınırlama).Sınırlandırmayı gerçekleştiren karakterler {} karakterleridir. adette olacak şekilde de Bir örnek verecek olursak; /de{1,3}f/ şeklinde kodladığımız pattern in anlamı şudur: başta d en sonda f karakteri olacak arada da 1 veya 2 veya 3 adet e karakteri olacak. Bu durumda bulunacak örnekler şunlardır.def, deef, ve deeef. Anlaşıldığı üzere df ve deeeeef gibi stringler değerlendirilmeyecektir.Tam karakter adetini de tabii ki verebiliriz.d ile f arasında 3 adet e olan stringleri elde etmek istiyorsak, patternimiz şöyle tanımlanacaktır: /de{3}f/ .Ayrıca En az ve en fazla adette olanları da buldurabiliriz.Örneğin,d ile f arasında en az 3 tane e olanları bulalım istiyorsak pattern tanımı: /de{3,}f/ şeklinde olur, En fazla 3 tane e olacaksa tanımımız şudur: /de{0,3}f/ burada başlangıç değeri 0 olarak kullanılmak zorundadır. {} [] karakterlerini öğrendiklerimiz çerçevesinde birlikte de kullanabiliriz. Ör: /[a-z]{1,3}/ paterni 1 veya 2 veya 3 küçük harf bulma işlevi görür. /.{3}/ paterni ise 3 karakter bulur. SEÇİM YAPMA KARAKTERİ: | | karakteri kendisinin sağ veya solunda bulunan örneklerden birini seçme işlevi görür. (veya anlamında) Örneğin, /def|ghi/ paterni def VEYA ghi stringini, /[a-z]+|[0-9]+/ paterni ise 1 veya fazla küçük harf VEYA 1 veya fazla rakam bulur matches one or more lowercase letters or one or more digits. Örnek Program : Bu program basit bir tamsayı(decimal) geçerlilik programıdır. Adı pat8.pl. #!/usr/local/bin/perl print ("Bir tamsayı giriniz:\n"); $number =<STDIN> ; chop ($number); if ($number =~ /^-?\d+$/) { # burada ^ ve $ tamsayı kontrulu için sınırlardır # tamsayı bu karakterler arasında kontrol ediliyor # - ve ? işareti negatif işaretinin varlığını # \d+ ise 1 veya fazla rakamın varlığını test ediyor print ("$number kurallara uygun bir tamsayıdır.\n"); } else { print ("$number tamsayı değildir.\n"); } Çalışması: >pat8.pl Bir tamsayı giriniz: -135 -135 kurallara uygun bir tamsayıdır. > >pat8.pl Bir tamsayı giriniz: 43.9 43.9 tamsayı değildir. > PATTERN BÖLÜMLERİNİN YENİDEN KULLANIMI Aşağıdaki özelliklere sahip bir örneği test edecek pattern yazalım. - 1 veya fazla rakam VEYA küçük harfler [\da-z]+ - onları takiben : veya ; karakterleri [:;] - onları takiben 1 veya fazla rakam [\da-z]+ - onları takiben : veya ; karakterleri [:;] - onları takiben 1 veya fazla rakam [\da-z]+ Yukardaki özellikleri içeren paternimiz /[\da-z]+[:;][\da-z]+[:;][\da-z]+/ kodlamasıyla ifade edilebilir. Burada [\da-z]+ ve [:;] pattern bölümlerinin tekrar edildiğini görüyoruz. Bu da kodlamayı ve incelemeyi zorlaştırdığı için perl daha kısa bir yol sunmuştur. Şöyleki yapılacak basit bir kodlama farkıyla tekrarlanan bu pattern bölümleri depolanır ve numaralanır. Örneğin tekrarlanan ilk pattern ([\da-z]+) şeklinde belirlenir(hafızaya depolanır) (Aynı zamanda numarası 1 dir kodlaması ise \1 biçimindedir). Sonraki [\da-z]+ görülen yerlere \1 koyabiliriz artık. paternimizin yeni kodu hazırdır: /([\da-z]+])[:;]\1[:;]\1/ Tekrarlanan [:;] bölümüne de aynı mantık uygulanırsa ( ([:;]) olarak depolanır. Numarası \2 dir) paternimizin son şekli belirlenmiş olur: /([\da-z]+)([:;])\1\2\1/ Kısaca ilk ve son durumu karşılaştırmak amacıyla görelim. İlk kodlama : /[\da-z]+[:;][\da-z]+[:;][\da-z]+/ Son kodlama : /([\da-z]+)([:;])\1\2\1/ Örneklerimiz de (genel de Perl de)bolca kullanacağız.Karışıklılığa neden olmaması için bunların kullanımlarına çok dikkat etmeliyiz. Aşağıdaki pattern, /\d{2}([\W])\d{2}\1\d{2}/ özel karakter kullandık ve daha sonra da 2 rakam,1 adet kelimede kullanılmayan karakter(Bunu hafızaya aldık),2 rakam ve tekrar kelimelerde kullanılmayan karakter ve tekrar 2 rakam örneğine uyar.Bu örneği tarih aratma için düşündüğümüzü varsayalım.Aşağıdaki örnekler bu patterne uyarlar: 12-05-92 26.11.87 07 04 92 aşağıdaki uymaz. 21-05.91 çünki . yerine - aranır. Dikkat ettiyseniz \d{2} için hafızaya alma işlemi uygulamadık. Çünkü o takdirde ilk elde edilen 2 rakam diğerlerine de uygulanırdı ve (örneğimizin tarih kontrolu olduğunu düşünürsek) tarih işlemlerinde sorun çıkardı.Gün değerinin,ay ve yıl ile aynı olanı geçerli örnek olurdu. Biraz açarsak /\d{2}([\W])\d{2}\1\d{2}/ ile /(\d{2})([\W])\1\2\1/ aynı sonucu vermezler 2.örneğe uyan bir string 05-05-05 şeklinde olurdu 05-12-99 gibi değil. $n hazır skalar değişkeni: Özellikle ondalık noktalı patern işlemlerinde /-?(\d+)\.?(\d+)/ gibi paternler kullanacaksak \1 ,ilk (\d+) 'i temsil eder.Diğerine aynı numara verilemez.Bu sorunu aşmak için hazır $n (n patern dizisini temsil eden rakamdır) özel değişkeni kullanılır. Örneğin, $string = "bu stringte şu sayı var 25.11."; $string =~ /-?(\d+)\.?(\d+)/; $tam = $1; $ondalik = $2; Bu kodlamayı incelersek, /-?(\d+)\.?(\d+)/ patterni 25.11 i bulur $1 ilk (\d+) yi $1 ikinci (\d+) yi temsil eder. 25 $1 de,11 ise $2 de depolanır ve diğer değişkenlere atanır. Dikkat edilecek bir nokta da şudur:$1 ve $2 daha sonra başka patern işlemlerinde kullanılırsa içerikleri değişeceğinden değerlerini başka değişkenlere atayarak kullanabiliriz. Başka bir hazır skalar değişken: $& Bu değişken /-?(\d+)\.?(\d+)/ patterninde tam patern örneğini saklar Kısaca; $string = "bu stringte şu sayı var 25.11."; $string =~ /-?(\d+)\.?(\d+)/; $sayı = $&; kodlamasında $& içeriği 25.11 dir. Pattern lerde kullanılan karakterlerde öncelik sırası: 1. 2. 3. 4. () +,*,?,{} ^,$,\b,\B | Örnek program : pat9.pl.Bu program tarih sınaması yapar. girilen tarihi sınar.Ayrıca 1900 lu yıllarda değilse 20.yy a ait değil mesajı verir. #!/usr/local/bin/perl print ("YYYY-MM-DD formatında tarih giriniz:\n"); $tarih = <STDIN>; chop ($tarih); # Komplike olan bu değeri parçalara ayırıp # skalar değişkenlere ve daha sonra yerlerine, # koyalım. # 31 günlük ay $ay31 = "(0[13578]|1[02])\\2(0[1-9]|[12]\\d|3[01])"; # 30 günlük ay $ay30 = "(0[469]|11)\\2(0[1-9]|[12]\\d|30)"; # Şubat ve artık yıl $ay29 = "02\\2(0[1-9]|[12]\\d)"; # 20.asır (1900 lü yıllar) $ornektarih = $tarih =~ /^(19)?\d\d(.)($ay31|$ay30|$ay29)$/; # geçerli tarih ama 20.yy değil $eskitarih = $tarih =~ /^(\d{1,4})(.)($ay31|$ay30|$ay29)$/; if ($ornektarih) { print ("$tarih geçerli bir tarih\n"); } elsif ($eskitarih) { print ("$tarih 20.yy a ait değil\n"); } else { print ("$tarih geçersiz bir tarih\n"); } Çalısması: >pat9.pl YYYY-MM-DD formatında tarih giriniz: 1999-11-18 1999-11-18 geçerli bir tarih >pat9.pl YYYY-MM-DD formatında tarih giriniz: 2000-12-12 2000-12-12 20.yy a ait değil >pat9.pl YYYY-MM-DD formatında tarih giriniz: 1899-12-12 1899-12-12 20.yy a ait değil >pat9.pl YYYY-MM-DD formatında tarih giriniz: 1999-13-12 1999-13-12 geçersiz bir tarih PATTERN BULMA SEÇENEKLERİ Pattern örnekleri bulma işlemleri anında işimize yarar özellikler içeren bazı seçenekler kullanılır. Bunların tablosu aşağıdadır. Tablo Seçenek İzah g Tüm örnekleri bul i Durumuna(case) aldırma m Stringi çoklu satırlı olarak kabul et o Sadece bir kez değerlendir s Stringi tek satırlı olarak kabul et x Pattern deki whitespace(boşluk,tab, v.b) lere aldırma Tüm bu seçenekler patternin hemen ardından kodlanır. Örneğin i seçeneğini kullanacaksak şeklinde kodlarız.Bu seçeneklerden birden fazlasıda birarada kullanılabilir.Şimdi bu seçenekleri inceleyelim. /ab*c/i Mümkün olan tüm örnekleri bul /g seçeneği: /g seçeneği patternin tüm örneklerini bulur. Örneğin,pattern /.ta/g ise anlamı şudur.Aranan stringlerden, herhangi bir karakteri takiben ta ile devam eden varsa onları bul. Bu durumda ata,eta,bal(ata),sal(ata) v.b uygun örneklerdir. Örneğin aranan string salata ise ata örneği elde edilir. Yine patternimiz /.a/g ve stringimiz salata ise bulunan örnekler:sa,la,ta dır. bunlar dizilere atanabilir ve kullanılabilirler. Ör: @dizi1 = "salata" =~ /.a/g; ise @dizi1 dizi değişkeni içeriği (eleman listesi) şu şekildedir.("sa", "la", "ta") Bu anlatımları isterseniz bir program halinde kodlayalım. Program adı.pat10.pl olsun. #!/usr/local/bin/perl while ("salata" =~ /.a/g) { $match = $&; #sistem değişkeni olan $& 'nın daima bulunan son pattern örneğini # içerdiğini hatırlayınız. print ("$match\n"); } Çalışması: >pat10.pl sa la ta > Durumuna aldırma ( - case insensitive-) /i seçeneği: Pattern de bulunankarakterlerin aranan stringte küçük veya büyük harf olmasına aldırmaksızın bulur. Örneğin; /ve/i patterni ve, vE, Ve, or VE örneklerini bulur. Coklu satırlı string /m seçeneği: Bu seçeneği ifade eden /m kullanıldığında perl stringin birden çok satır içerdiğini kabul eder.^ karakteri string başlangıcını ya da yeni satır başlangıcını bulur. Ör: /^İkinci/m patterni , Önek satır\nİkinci satır başlangıcı stringinde İkinci kelimesini bulur Satır sonundaki kelimeleri de $ karakteri özelliğinden yararlanarak buluruz. Ör: /sonu.$/m patterni ile Birinci satır sonu.\nDiğer satırın sonu. satırındaki sonu. kelimeleri bulunur. Patterni sadece bir defa değerlendir /o seçeneği: /o seçeneğiyle bulunan pattern örneği bir defa değerlendirilir,işleme sokulur. aynı pattern bulma satırı bir kaç defa daha işlense dahi ilk değerlendirilen değer hala geçerlidir. Ör $var = 17; while ($var > 0) { $string = ; $string =~ /abc/$var/o; print ($string); $var--; # yerleştirilen string hala 17 dir } Tek satırlı string /s seçeneği: Önekle inceleyelim. $string = "This is a\ntwo-line string."; $string =~ s/a.*o/one/s; # $string içeriği şu anda "This is a one-line string." tir. m seçeneğini ^ ve $ ile kulanma örnekleri. $string = "The The first line\nThe The second line"; $string =~ s/^The//gm; # $string içeriği : "The first line\nThe second line" $string =~ s/e$/k/gm; # şu anda $string içeriği "The first link\nThe second link" Pattern lerde White Space karakterleri kullanımı x seçeneği: x seçeneği Perl'e ,stringlerde white space(\n,\t,\f,\r, ve boşluk) karakterlerine aldırmamasını söyler (önlerinde \ karakteri olmadıkça)ve onları eler. $string =~ s/\d{2} ([\W]) \d{2} \1 \d{2}/$1-$2-$3/x patterni örneğinde gün-ay-yıl stringi dd-mm-yy formatına cevrilir. Diğer Ayraçlar: Gördüklerimiz dışında başka ayraçlarda vardır.#,[,< gibi. Bir örnek : s#/u/bin#/usr/local/bin# /u/bin yerine /usr/local/bin yerleştirir. aynı işi aşağıdaki kodlamalar da yapar. s(/u/bin)(/usr/local/bin) s/\/usr\/local\/bin/ Çeviri operatörü :tr Genel biçimi tr/string1/string2/ şeklindedir.string1 bulunur yerine string2 yerleştirilir. Ör: $string = "abcdefghicba"; $string =~ tr/abc/def/; kodlaması ile $string 'in son hali şudur: defdefghifed Anlaşılacağı gibi a yerine d,b yerine e,c yerine f yerleşmiştir. Genelde küçük ve büyük harf çeviröelerinde kullanılır. Örnek program : pat11.pl #!/usr/local/bin/perl while ($line =<STDIN> ) { $line =~ tr/A-Z/a-z/; print ($line); } Çalışması: >pat11.pl BÜYÜK HARFLE YAZIYORUM,KÜÇÜK HARFE DÖNÜŞTÜRECEK. büyük harfle yazıyorum,küçük harfe dönüştürecek. KArışıK Yazdım KÜÇÜK YAZACAK. karışık yazdım küçük yazacak. > ^D Not : patern özel karakterlerinde bu dönüşümü sağlamak için tr yerine y kullanırız. Ör : $string =~ y/a-z/A-Z/; ÇEVİRİ OPERATÖRLERİ SEÇENEKLERİ Çeviri operatörleri için 3 seçenek kullanılabilir. Seçenek Anlamı ------- -------------------------------c Tanımlı olmayan karakterleri seç d Tanımlı tüm karakterleri sil s Birçok aynı çıktı karakterinin , çıktı için sadece 1 tanesini seç Ör: $string =~ tr/\d/ /c; ifadesi, rakam olmayan herşeyi ,bir boşluk olarak yerleştirir. $string =~ tr/\t //d; ifadesi, tanımlı her karakteri (tab ve boşluk),$string'ten siler. $string =~ tr/0-9/ /cs; ifadesi,rakam olmayan herşeyi,rakamlar arasında sadece 1 boşlukla çıktı olarak yerleştirir. Örnek Program : Program adı:pat12 olsun. #!/usr/local/bin/perl $string =<STDIN> ; $string =~ tr/0-9//cd; print ("$string\n"); Çalışması: >pat12.pl Bu stringte 45 var. 45 > Bu örnekte $string içindeki rakam olmayan karakterler seçilerek(c) silinmiştir(d). Memory de saklamaksızın parenteze alma: ?: Bu işlev için ?: karakterleri kullanılır. Ör: /(?:a|b|c)(d|e)f\1/ Bu örnekle şu işlemler yapılır, a, b, veya c nin biri, a|b|c) d veya e nin biri, (d|e) f f daha önce bulunan d veya e den biri \1 burada \1 in a|b|c değil (d|e) i temsil ettiği görülür. Çünkü (?:a|b|c) paterninde bulunan ?: karakteri bu parentez içinin memoriye saklanmasını önlemiştir. Aşağıdaki ifadede ise \1 ile (a|b|c) temsil edilir. /(a|b|c)(d|e)f\1/ kıyaslayarak anlayınız. ?? VE reset FONKSİYONLARI İLE PATTERN BULMA ?? operatörü // ile aynı işi görür ama döngü içinde ise sadece bir kez işler. while ($satir =~ ?abc?) { komutlar } #?abc? pattern' i ikinci defa çalışmayacaktır. eğer yeniden patterni kullanmak istersek reset fonksiyonuyla çağrılır. Bu durumu gösteren bir örnek program aşağıdadır. Örnek #!/usr/local/bin/perl while ($satir = <STDIN>) { last unless ($satir =~ ?\bBu\b?); print ("$satir"); reset; } çalıştır > Bu ilk satırdır. Bu ilk satırdır. Bu da sonraki satırdır Bu da sonraki satırdır Son satir. > NOT : reset fonksiyonu ayrıca adı tanımlanan karakterle başlayan tüm değişkenleri temizler(null). örneğin; reset ("w"); kodu ile adının ilk karakteri w olan değişkenler içine null string atanır. Ayrıca dizilere de uygulanır. Örneğin aynı mantıkla @wdizi isimli dizinin tüm elemanlarına null atanır. reset ("ae"); - a veya e ile başlayanları temizler reset ("a-d"); - a ile d arası hangisi olursa temizler * çok dikkatli olunmalıdır. AKIŞ KONTROL İFADELERİ Bu konuyla ilişkili olarak 3.dersi görmüştük. Şimdi dersi biraz daha genişletiyoruz. Tek satırlı şart ifadesi Daha evvel if ifadesini şöyle kullanmıştık, if ($var == 0) { print ("Bu sıfırdır.\n"); } Bu ifadeyi tek satırda gösterme özelliği de vardır. print ("Bu sıfırdır.\n") if ($var == 0); her iki örnekte aynı işleve sahiptir. Bu biçim unless,until,while gibi şart ifadelerinde de kullanılır. Ör: print ("Bu sıfırdır.\n") unless ($var != 0); print ("Henüz sıfır değil.\n") while ($var-- > 0); print ("Henüz sıfır değil.\n") until ($var-- == 0); Tek satırlı komut kullanımlarında özellikle döngü değeri artış ifadelerinde hata yapma ihtimali olduğundan bu tip ifadeler de dikkatli kullanılmalıdır. Örneğin, $count = 1; print ("$say\n") while ($say++ < 5); ifadelerinde ekrana basılan ilk değer 2 dir.1 değildir. v.b.... Örnek program : Adı:whprg1.pl olsun #!/usr/local/bin/perl $say = 0; print ("$say\n") while ($say++ < 5); Çalışması : >whprg1.pl 1 2 3 4 5 > FOR DÖNGÜSÜ KULLANIMI For döngüsü kullanımını bildiğiniz bir döngü çeşididir. Genel format: for (ilk değer ataması; koşul; sayac arttırma) { komut satırları bloğu } Örnekle inceleyelim program adı forprg1.pl olsun #!/usr/local/bin/perl for ($sayi=1; $sayi <= 5; $sayi++) { print ("$sayi\n"); } # 1.ilk değer atanır # 5 ten kucuk veye eşit mi? sorusunun cevabı evet ise döngüye girilir # sayı yazdırılır # sayac 1 arttırılır ve tekrar koşul sınanır. # koşul sonucu evet ise işlem bir önceki gibi devam eder,hayır ise döngü dışına çıkılır. Çalışması : >forprg1.pl 1 2 3 4 5 > For dögülerinde bazen her bir değer artışından(döngü sayacı) evvel birden fazla komut uygulamak gerekebilir. Bu durumda for döngüsünde , (virgül) kullanılır. Örneğin aşağıdaki program parçasını inceleyelim ve aynı işlemleri for ile nasıl kullandığımızı görelim. $satir = <STDIN>; $say = 1; while ($say <= 3) { print (satir); satir = <STDIN>; $say++; } Bu satırlarla yapılanı for ile gerçekleştiren programın kodu aşağıdadır. #!/usr/local/bin/perl for ($satir = <STDIN>, $say = 1; $say <= 3; $satir = <STDIN>, $say++) { print ($satir); } FOREACH döngüsü ---- Liste ve Dizi elemanlarını okuma Genel formatı: foreach localdeğişken (liste-dizi) { deyimler grubu; } foreach dizilerden kolaylıkla eleman almak amacıyla kullanılan, perl'e has bir zenginliktir. Diziden liste elemanı local değişkene atanır. Her dönüşte sıradaki liste elemanı alınır. Bu deyim programlarda çok kullanılır. Örnek program : Program adı forprg2.pl olsun #!/usr/local/bin/perl @words = ("Bu", "bir", "liste", "dir."); foreach $word (@words) { print ("$word\n"); } Çalışması: >forprg2.pl Bu bir liste dir. > Bir başka örnek program : forprg3.pl program ekrandan girilen satırdaki kelimeleri sıralar ve ters sıraya sokar ve basar. #!/usr/local/bin/perl $line = <STDIN>; $line =~ s/^\s+//; $line =~ s/\s+$//; foreach $word (reverse sort split(/[\t ]+/, $line)) { print ("$word "); } print ("\n"); Çalışması: > test icin bir satir girdim test satir icin girdim bir > Çalışmanın Açıklaması: Önce split ile satirdaki kelimeler bölünür. ("test", "icin", "bir", "satir" , "girdim") sonra bunlar sıralanır.(hazır fonksiyon olan sort ile) sıralama sonucu listenin durumu: ("bir", "girdim" , "icin", "satir" , "test") Bir sonraki aşama da liste ters sırada sıralanır.(reverse hazır fonk.) listenin son durumu: ("test", "satir" , "icin", "girdim" , "bir") olur. Bu durumdaki liste ekrana basılır. DO DEYİMİ: genel format: do { deyimler bloğu } while_veya_until (şart_ifadesi); biçimindedir. Örnek kullanım: do { $line = <STDIN>; } while ($line ne ""); satır sonu değilse döngü devam eder. Aynı sonucu aşağıdaki kodlama da verir. do { $line = <STDIN>; } until ($line eq ""); Buradaki şart ifadesinde ise satır içeriği boş olana(giriş yok) kadar döngüyü uygular. Örnek program : doprg.pl #!/usr/local/bin/perl $sayac = 1; do { print ("$sayac\n"); $sayac++; } until ($sayac > 5); >doprg.pl 1 2 3 4 5 > LAST deyimi: Döngüden çıkışı sağlar. Örnek program: lastprg.pl #!/usr/local/bin/perl $toplam = 0; while (1) { $satir = <STDIN>; if ($satir eq "") { last; } chop ($satir); @sayilar = split (/[\t ]+/, $satir); foreach $sayi (@sayilar) { if ($$sayi =~ /[^0-9]/) { print STDERR ("$sayi sayi degil\n"); } $toplam += $sayi; } } print ("Toplam: $toplam.\n"); Çalışması: >lastprg.pl 457 2 11 6 ^D Toplam: 35. > NEXT deyimi : Döngüde, Bir sonraki dönüşe atlatır. Örnek Program: nex.pl #!/usr/local/bin/perl print ("Toplam için son sınır sayısını gir:\n"); $limit = <STDIN>; chop ($limit); $say = 1; $toplam = $cifttoplam = 0; for ($say = 1; $say <= $limit; $say++) { $toplam += $say; if ($say % 2 == 1) { # sayı tek ise sonraki dönüşe atla next; } $cifttoplam += $say; } print(" 1 den $limit ye kadar olan sayıların toplamı: $toplam\n"); print("Bu sınırdaki çift sayıların toplamı ise: $cifttoplam\n"); Çalışması: >nex.pl Toplam için son sınır sayısını gir: 7 1 den 7 ye kadar olan sayıların toplamı: 28 Bu sınırdaki çift sayıların toplamı ise: 12 > Bir başka next örneği içeren program: nex2.pl. Bir kelime sayma programıdır. #!/usr/local/bin/perl $toplam = 0; while ($satir = <STDIN>) # kelime girişi yap, ctrl+d ye basılırsa döngüden çıkılır { $satir =~ s/^[\t ]*//; # baştaki boşluk ve tabları at $satir =~ s/[\t ]*\n$//; # sondaki boşluk,tab ve \n karakterlerini(yeni satır) at next if ($satir eq ""); #satır boşsa sonraki dönüşe atla @kelimeler = split(/[\t ]+/, $satir); # kelimeleri aralarındaki # boşluk ve tab'lardan # ayırarak diziye yerleştir $toplam += @kelimeler; # dizi boyutundan elde edilen eleman (kelime) # sayısı değerini tut } print ("Toplam kelime sayısı: $toplam\n"); Çalışması: >nex2.pl Bir kac kelime girelim program kelime sayısını versin. ^D Toplam kelime sayısı: 8 REDO DEYİMİ : Döngüdeki bir dönüşü yeniden başlat Örnek programla inceleyelim. redoprg.pl #!/usr/local/bin/perl $toplam = 0; for ($say = 1; $say <= 3; $say++) { $satir = <STDIN>; last if ($satir eq ""); $satir =~ s/^[\t ]*//; $satir =~ s/[\t ]*\n$//; redo if ($satir eq ""); @kelimeler = split(/[\t ]+/, $satir); $toplam += @kelimeler; } print ("Toplam kelime sayısı: $toplam\n"); Çalışması: >redoprg.pl Test satırı. Bu da ikincisi. ^D Toplam kelime sayısı: 5 > VERİLEN ETİKETE GİTME : Bazen dallanmalarda programın herhangi bir bölümüne atlamamız gerekir. Bu bölümlere ulaşmak için bölüme ait etiket adı veriler. Aşağıda kullanılan DONE: sintaksı bir etiketi belirler. next ve redo ile de etiket kullanılır. (redo etiket; gibi). Örnek program : etprg.pl #!/usr/local/bin/perl $toplam = 0; $ilksayac = 0; DONE: while ($ilksayac < 10) { $ikincisayac = 1; while ($ikincisayac <= 10) { $toplam++; if ($ilksayac == 5 && $ikincisayac == 9) { last DONE; } $ikincisayac++; } $ilksayac++; } print ("$toplam\n"); Çalışması: >etprg.pl 59 > CONTİNUE bloğu: Örnek görerek anlamaya çalışalım: $i = 1; while ($i <= 10) { print ("$i\n"); } continue { # continue bir blokla kullanılır ({ } arasında) $i++; } Yukardaki örnekte continue bloğundaki $i++ aşağıda for bloğundaki görevi yapar. for ($i = 1; $i <= 10; $i++) { print ("$i\n"); } Her iki örnekteki çalışma aynıdır.continue genelde while ve until ile kullanılır. for da buna gerek yoktur. GO TO etiket deyimi: go to yanında belirtilen etikete program akışını yönlendirir. etiket, do veya altyordam(sub) içinde tanımlı olmamalıdır. Ör: #!/usr/local/bin/perl NEXTLINE: $line = ; if ($line ne "") { print ($line); goto NEXTLINE; } Çalışması: bu bir satırdır. bu da bir satırdır. ^D > BİLEŞİK DİZİLER Bu diziler normal tanımlanmışlardır. dizilerde,dizi elemanlarının bilinememesi ihtiyacını karşılamak amacıyla Örneğin : @dizi dizisinin 1.elemanı $dizi[1] dir ve içeriğini bilmek ise zordur. Oysa ki bileşik dizilerde elemanda bulunan değerin kendisi indistir. $dizi[1] içeriği muz değerini taşıyor olabilir ve bu değeri dışardan anlamak zordur. Bileşik dizide ise $dizi{"muz"} gösterimi vardır. Yani değer indistir. Bu da bir çok kolaylığı beraberinde sunar. Öncelikle bileşik dizilerin tanımından başlayalım. Normal dizi tanımında dizi değişkeni adının başında @ karakteri vardı(@meyvalar ...gibi). Bileşik dizi değişkeninin başındaki karakter ise % karakteridir. Bir meyvalar isimli bileşik dizi tanımlayacak olursak, %meyvalar şeklinde kodlarız. Bir diğer fark ise normal dizilerde indis [] karakterleri içinde ifade edilirken bileşik dizilerde { } karakterleri içinde gösterilir. İndiste kullanılacak değerler skalar değer ve değişken adları olabilir. $personel_sicil{14159} $meyva{"kara_yemis"} $reel{3.14159} $tamsayi{-7} $meyva{$meyva_adi} yukarıdaki örneklerin hepsi geçerlidir ve bizlere büyük bir kullanım kolaylığı sağlar. BİLEŞİK DİZİLERE ELEMAN ATAMA VE EKLEME Atama şekli normalde aşağıdaki gibidir. $meyva{"elma"} = 1; burada %meyva bileşik dizisinin elma elemanına 1 değeri atanıyor. Örnek Program : Ekrandan meyva adı ve numarası girelim(nar mutlaka olsun). Enter basınca nar adlı meyvanın numarasını bassın. Adı ass1.pl #!/usr/bin/perl $girilen = <STDIN>; $girilen =~ s/^\s+|\s+\n$//g; %meyva = split(/\s+/, $girilen); print ("Nar numarası: $meyva{\"nar\"}\n"); Çalışması: >ass1.pl elma 1 armut 2 nar 3 Nar numarası: 3 > ayva 4 Bir başka örnek program : Bu program da ekrandan girilen satırlarda bulunan büyük harfle başlayan kelimeler ve adetleri bulunur ve basılır. Program adı : ass2.pl #!/usr/local/bin/perl while ($girilensatır = <STDIN>) { while ($girilensatır =~ /\b[A-Z]\S+/g) { $kelime = $&; $kelime =~ s/[;.,:-]$//; # noktalamalar siliniyor. $kelimelistesi{$kelime} += 1; } } print ("Buyuk harfli kelimeler ve sayıları:\n"); foreach $buyukharfli (keys(%kelimelistesi)) { print ("$buyukharfli: $kelimelistesi{$buyukharfli}\n"); } Çalışması : >ass2.pl Bu bir Giris satırıdır. Bu satırlarda Buyuk harfler vardır. ^D > Buyuk harfli kelimeler ve sayıları: Bu: 2 Giris: 1 Buyuk: 1 BİLEŞİK DİZİLERİ OLUŞTURMA Bu diziler tek bir atama ile oluşturulabilir ve daha sonra eleman ilavesi yapılabilir. %meyvalar = ("elmalar", 17, "narlar", 9, "incirler", "yok"); [ veya perl5 e ait bir atama özelliği olarak %meyvalar = ("elmalar" => 17, "narlar" => 9, "incirler" => "yok"); ] komutuyla oluşturulan bileşik dizinin index elemanları ve onların değerleri elmalar, 17, narlar, 9, incirler,yok şeklindedir %meyvalar dizisine daha sonra elemanı eklemek istersek, mesela, $meyvalar{"kiraz"} = 5; kodunu gireriz. Bu kodlama ile meyvalar isimli bileşik diziye, yeni bir eleman (indexi kiraz ve buradaki değer olarak ta 5) atanmış olur. Normal dizilerden de bileşik dizi oluşturabiliriz. Örneğin, @meyvalar = ("elmalar", 6, "kirazlar", 8, "muzlar", 11); %meyvalar = @meyvalar; satırları incelendiğinde bu işlemin nasıl gerçekleştiği anlaşılacaktır. Benzer mantıkla bileşik diziden de bileşik dizi oluşturulabilir. %meyvalar1 = ("elmalar", 6, "kirazlar", 8, "muzlar", 11); %meyvalar2 = %meyvalar1; ve pek kullanışlı olmamakla birlikte(dizi elemanlarının sırası belirlenmediğinden), bileşik diziden de normal dizi oluşturulabilir. %meyvalar = ("elmalar", 6, "kirazlar", 8, "muzlar", 11); @meyvalar = %meyvalar; hatta aynı anda diziler ve skalar değişkenlere birlikte de atama yapılabilir. ($degisken1, $degisken2, %bilesikdizi) = @dizi; ...gibi.. yukarda @dizi nin 1.elemanı $degisken1, 2. elemanı ise $degisken2,ye atanır. Sonraki elemanlar ise %bilesikdizi ye atanırlar. Örnek Program : Program girilen satırı split fonksiyonu ile bölerek bileşik dizi oluşturur. Program Adı:ass3.pl #!/usr/local/bin/perl $girilensatir = <STDIN>; #satır girişi:(meyva adı ve değeri şeklinde) $girilensatir =~ s/^\s+|\s+\n$//g; #baştaki ve sondaki boşluklar ayıklanır %meyva = split(/\s+/, $girilensatir); #satır kelimelere bölünüp,diziye #elemanlar olarak atanır print ("Muz sayısı: $meyva{\"Muz\"}\n"); Çalışması : >ass3.pl Nar 5 Elma 7 Muz 11 Kiraz 6 Muz sayısı: 11 > Diziye eleman eklemeyi görmüştük.Bu dizilerden eleman silmek için TEK YOL hazır fonksiyon olan delete kullanımıdır.(Bazı fonksiyonlar çeşitli silme işlemleri yaparlar ama bazı durumlarda karışıklığa yol açılabilir) Ör: delete($meyva{"Muz"}); satırı ile %meyva bileşik dizisinden Muz elemanı(indexi) silinir. DİZİ İNDEXLERİNİ VE DEĞERLERİNİ LİSTELEME Bileşik dizilerin indexlerini keys fonksiyonu elde eder. %meyva = ("nar", 9, "muz", 23, "ayva", 11); @meyvaindex = keys(%meyva); Yukardaki şekilde kodlanan satırların sonucu olarak,keys hazır fonksiyonu, %meyva bileşik dizisinin indexleri olan nar,muz ve ayva yı @meyvaindex dizisine atar. Bu atamayı alfabetik sırada yapmak istersek sort fonksiyonunu da eklememiz gerekir Ör: @meyvaindex = sort keys(%meyva); Bileşik dizilerin indexlerini keys fonksiyonu elde eder demiştik değerlerini ise values hazır fonksiyonuyla elde ederiz. %meyva = ("nar", 9, "muz", 23, "ayva", 11); @meyvaindex = values(%meyva); @meyvaindex dizisinin elemanları; (9, 23, 11) dir. Bir Bileşik dizinin elemanlarına döngü şeklinde erişim(tüm elemanlarına sırayla erişim). Bu işlem için daha önce gördüğümüz keys ve foreach kullanılabileceği gibi, each hazır fonksiyonuda kullanılabilir. Örnek: %kayit = ("Mavis", 16, "Arif", 27, "Dinc", 51); foreach $tut (keys(%kayit)) { . . . # sonraki satırlar } Arif, Mavis, ve Dinc ,$tut değişkenine atanırlar. Bu yöntemle indexlere erişildi ama değerlere erişemedik. Değerlere erişim için de yine aynı mantıkla yeni bir foreach döngüsü kullanmamız gerekir. Ama perl bu kullanımın yerine işimizi çok daha kolaylaştıracak olan each fonksiyonuna sahiptir. Bu fonksiyonla hem index hem değeri elde etmek mümkündür. Ör: %kayitlar = ("Mavis", 16, "Arif", 27, "Dinc", 51); while (($tut, $kayit) = each(%kayitlar)) { # satırların devamı } yukarda ilk satırda index ve değerler den oluşan bileşik dizi elemanları, diziyi oluştururlarken while döngüsünün her dönüşünde bu diziye ait index ve değer çifti skalar değişkenlere atanır. $tut, indexi, $kayit ise değeri alır. (ilk dönüşte bunların değerleri Mavis ve 16 dır. Sonraki dönüşlerde aynı kurala göre işler). KOMUT SATIRI SEÇENEKLERİ Bir perl programına seçenek geçirmenin iki yolu vardır. 1. Komut satırında 2. Programın ilk satırında KOMUT GİRME SATIRINDAN SEÇENEK Syntax : Perl seçenek program adı Örnek : $ perl -s -w test1 c↵ komutu ile test1 programı –s ve –w seçeneklerini alır ve çalışır. Bazı seçeneklerde değer alabilir. Örnek : $ perl -0 26 test1 ↓ integer Aradaki boşluğu (seçeneklerde) kaldırarak da aynı iş yapılır. $ perl -026 test1 ...gibi $ perl -sw test1 ...gibi $ perl -sw026 test1 ...gibi PROGRAMDA SEÇENEK TANIMLAMA #!/usr/bin/perl –w # perl4 te tek seçeneğe izin var. Perl5 serbest # ama bazı sistemler 32 karakterden fazlasını almıyor. Not : Komut satırında perl –s test1 ↵ girmişsek programın ilk satırı ise #!usr/bin/perl –w ise Program çalışırken sadece –s seçeneği ile çalışır. –w dikkate alınmaz. SEÇENEKLER -v : Perl’in versiyonunu verir. $ perl -v test1 ↵ -c : syntax’ı kontrol eder. $ perl –c test1 ↵ Program çalıştığında test1 syntax ok mesajı verir, hata varsa bildirir. -w : Yazım ikazı, program yazımında syntax değilde yazım kullanımı konusunda hata varsa kontrol eder. Mesela yanlış değişken adı veya = = yerine eq kullanılması gibi. Örneğin ; $y=$x; satırına geldik diyelim eğer $x tanımsız ise Identifier main::x ..... şeklinde mesaj verir.(Bunlarla ilgili geniş bilgiyi sonraki bölümlerde inceleyeceğiz.) Not : -w ile –c kullanımı hem syntax hem kullanım hatasının tespiti için yararlıdır. -e : Tek satır programı icrası (bir satırda birden fazla da kullanılabilir). Örneğin ; perl –e “print(‘Hello’);” –e “print(‘there’);” ↵ Ekrana : Hello there yazar. -s : Kendi komut satır seçeneklerinizi tedarik eder. Perl –s test1 –q ↵ program test1’i başlatır ve –q seçeneğini ona geçirir. Eğer –s yazmasaydık –q seçeneği programa geçmezdi. Seçenek tek karakterden fazla olabilir. $sebze değişkenini kullanacaksak perl –s test1 –sebze ↵ gireriz. $sebze’nin değeri 1’dir. (perl otomatikman 1 verir.) veya başka bir değer atama işi şu şekilde yapılabilir. perl –s test1 –sebze=”nar” ↵ $ ebze içeriği ”nar” olur. -P option : C preprocessor kullanma seçeneğidir. Perl –P örnekprog ↵ bu komutla örnekprog , C önişlemcisinden den alınır sonra icra için perl’e geçer. C önişlemcisi bize C deki bazı ifadelerini kullanma izni verir. # ile başlarlar. Örnek ; # define USER “ertan” # define EXPRES (14+6) define tanımlı makroya değer geçirir. # define bulunan bir perl program örneği : #!/usr/local/bin/perl -P #define AL_AF_INET 2 print ("Bir internet adresi giriniz:\n"); $makine = <STDIN>; $makine =~ s/^\s+|\s+$//g; @adres = split (/\./, $makine); $paket = pack ("C4", @adres); if (!(($ad, $adlar, $adrestipi, $uzunluk, @liste) = gethostbyaddr ($paket, AL_AF_INET))) { die ("Adres Bulunamadı.\n"); } print ("Tam adı: $ad\n"); if ($adlar ne "") { print ("Diger adları:\n"); @liste = split (/\s+/, $adlar); for ($i = 0; $i < @liste; $i++) { print ("\t$liste[$i]\n"); } } Çalışması : Bir Internet adresi giriniz: 194.27.16.7 Tam adı: sirius.gazi.edu.tr Diger adları : sir sirius Define ile ilgili bir başka kullanım : #define FIRST 1 #define SECOND FIRST $result = 43 + SECOND; ( yani 43+1) #include Kullanarak Diğer Dosyaları Alma : #include dosyaadı include bir başka C önişlemci komutu olup, tanımlı program parçasını dosya içeriğinine dahil etme işlevi görür. Örnek ; myincfile.h dosyasını dahil etmek için #include " incdosyam.h" (bu dosya local dizin’de aranır. diğer dizinlerde de aratmak icin –I opsiyonu kullanılır). Verilen patern’de arama için,örneğin; #include "/u/pub/incdosyam.h" şeklinde kodlanır. -I : bu seçenek C include dosyalarını aratır.-P ile birlikte kullanıldığında bu dosyaları hangi dizinde aranacağı belirtilmiş olur. perl -P -I /u/home/incdizin dosya birden fazla dizinde aratmak için; perl -P -I /u/home/incdizin -I //u/home/incdizin2 dosya Not : -I ile verilen dizinler @INC içinde saklanır. -n : Çoklu dosyalarla işlem seçeneğidir. Birden fazla giris (dosya/satır)okuması yapar. Unix’te birçok dosya ile işlem mesela komut satırından yapılabilir. (örneğin;Cat dosya1 dosya2 dosya3 komutu dosya1, dosya2, dosya3 dosyalarını okur ve ekrana basar v.b) Perl’de aynı işi <> operatörü ve döngü yardımıyla yapabiliriz. while ($line = <>) { } ------- satırlar ---- Bir başka metot da –n kullanımı ile gerçekleştirilir. Bu seçenek, komut satırından birden fazla girdi alır. Konuya ilişkin bir örnek görelim : Bu örnek girilen satırın iki yanına * koyar. Örnek ; #!/usr/bin/perl -n # giriş satırı sistem değişkeni olan $_içinde depolanacaktır. $line = $_; chop ($line); printf ("* %-52s *\n", $line); Çalışması ; Bu tek satırdır ↵ * Bu tek satırdır Bu da ikinci ↵ * Bu da ikinci * * -n seçeneği bu programı görünmez bir while döngüsüyle kapatmıştır. Komut satırından girilen değerler $_ içine depolanır. -n ile –e birlikte kullanişlıdır. Örneğin aşağıdaki komut cat komutuna eşittir. $ perl -n -e "print $_;" dosya1 dosya2 dosya3 veya daha basit olarak perl -n -e "print" dosya1 dosya2 dosya3 her üç dosya içeriği alt alta ekrana listelenir. $_ değişkeni default değişkendir. Hatta pattern örneklerde ve yerine koymalarda operatörler $_ üzerinden default işlem yaparlar. Örnek ; $ perl -n -e "print if /[0-9]/" dosya1 dosya2 dosya3 ↵ dosya1, dosya2 ,dosya3 'ü tarar rakam içeren girişleri (satırları) listeler. -p : Bu seçenekte –n ’e benzer farklı olarak okunan satırları basar. $ perl -p -e ";" dosya1 dosya2 dosya3 ↵ dosya1, dosya2, dosya3 içerikleri okunur ve alt alta ekrana basılır. (yukardaki örnek unix'teki Cat dosya1 dosya2 dosya3 komutuyla aynıdır.) -p seçeneği –i ile de çok kullanılır. Not : -p ve –n birlikte kullanılırsa, -n dikkate alınmaz. -i : Dosya yazma (editing)seçeneğidir Görüldüğü üzere –p ve –n seçenekleri komut satırında tanımlı dosyaları okuyordu. –i seçeneği, -p ile kullanıldığında, dosyadan okuduğunu tekrar oraya yazma amacıyla kullanım işlevini sağlar (unix’deki sed gibi dosyayı edit etme işlevi). $ perl -p -i -e "s/fgh/xwz/g;" dosya1 dosya2 dosya3 komutu ile dosyalardaki fgh yerine xwz konulur. -a : Satırı kelimelere ayırarak listeye (dizi)dönüştürme seçeneğidir. Bu seçenek -n veya –p ile kullanılır ve satırı otomatikman kelimelere ayırır (white space karakteri olmayan). Bu kelimeler @F sistem dizi değişkeninde saklanırlar. –a seçeneği satırda istenenleri çekip çıkarmada çok yararlıdır. Örneğin programa girişi yapılan satır Bu bir deneme kaydıdır ise @F sistem dizi değişkeninin içeriği şu şekildedir: ("Bu", "bir", "deneme", "kaydıdır") Mesela; Okunacak dosya adı datadosya ve kayıt formu şöyle olsun. Ad No Toplam girilmiş kayıtlar ise, Bertan TURK 103 ertan NAR 10 nur TABAK 1023 474.32 57.32 4700.32 -n ve –a kullanılarak dosyadan No ve Toplam alanlarını cekip çıkaran ve yazdıran bir program örneği; #!/usr/local/bin/perl while ($F[0] =~ /[^\d.]/) { shift (@F); next if (!defined($F[0])); } print ("$F[0] $F[1]\n"); bu programın adı prog.pl olsun /usr/local/bin/perl -a -n prog.pl datadosya ↵ 103 474.32 10 57.32 1023 4700.32 -F : (split) ayırma patterni tanımlama seçeneğidir. Kelimeleri ayırırken ayraç karakteri de koyar. –a ile birlikte kullanım için dizayn edilmiştir. Önceki programı aşağıdaki gibi çağrılmış olsun; /usr/local/bin/perl -a -n -F:: prog.pl datadosya ↵ Bu durumda dosya okunurken kelime aralarına : : yerleştirilir. Bertan TURK:: 103::474.32 gibi... Not : Normal split'de :: işaretleri // içine alınırdı. Burada bu karakterler olsada olur olmasada yani /::/ ile :: aynıdır. -0 : (O harfi değil, Sıfır'dır)Satır sonu girişini tanımlayan seçenektir. Şu ana kadar giriş satırlarını dosyadan veya klavyeden okuyorduk sonunda \n karakteri vardı. Biz istersek sondaki bu karakteri –0 seçeneği ile kendimiz belirliyebiliriz. Bu ASCII (8 tabanlı - octal) olarak belirlenebilir. Örneğin ; Boşluk karakterinin octal değeri 040 dır. Perl -0 040 prog.pl okunandosya ↵ Komuyuyla prog.pl programı çağrılır onun okuma yaptığı okunandosya’nın satır sonu karakteri olarak boşluk karakteri kullanılması sağlanır. Konuyu iyice anlamak için diyelim ki data.txt dosyamız var ve içeriği de şöyle: (tabiiki satır sonlarında \n -satır sonu- karakteri var) Bu ilk satır ikinci satır ucuncu satır Perl programımızın adı prog.pl ve içeriği de aşağıdaki kodlama olsun. #!/usr/local/bin/perl -0040 while ($line = <>) { $line =~ s/\n//g; next if ($line eq ""); print ("$line\n"); } Calıştırdığımızda ekran dökümü aşağıdaki gibi olacaktır. $ prog.pl data.txt ↵ Bu ilk satırikinci satırucuncu satır $ - l (küçük -le- harfi) :Satır sonu çıktısı tanımlama seçeneğidir. Bu seçenek size belirlenen satır sonu karakterinin print fonksiyonu ile basılmasını sağlar. 0 gibi –l de octal değerle kullanılır(ASCII karakterin değeridir). Bu opsiyon tanımlanınca perl 2 şey yapar. 1. Eğer –p veya –n opsiyonu tanımlıysa klavyeden girilen satırdaki son karakteri kaldırır. 2. Print fonksiyonu çağrılınca –l ile tanımlanan karakter basılır. Örnek Program ; Bu program kelimeler arasına ascii kodu 197 .(Octal değeri 305 dir) olan karakteri basar. Program adı program.pl olsun. #!/usr/bin/perl -l305 print ("Merhaba"); print ("Bu ikinci kelime"); print ("Bu da 3. kelime"); Çalışması : program.pl MerhabaÅBu ikinci kelimeÅBu da 3. kelimeÅ -x : Bir mesajdan bir program çekip alma seçeneğidir. Örneğin bir file içeren elektronik mail mesajından programı almak gibi. -x opsiyonu tanımlıysa perl tüm satırları görmezlikten gelir taki başlık satırını görene kadar. Bunu anlaması, başta #! Karakterlerlerini görmesiyle olur. Eğer perl5 kullanıyorsak başlık satırı ayrıca perl kelimesini içermelidir. #! ve "perl" görülünce , aşağıdaki 3 şarttan biri gerçekleşinceye kadar proses devam eder. 1 2 3 Program sonuna gelindiğinde, Ctrl+D veya Ctrl+Z karakterine gelindiğinde _ _END_ _ ifadesi içeren satıra gelindiğinde Örnek Program ;Bir program içinde perl program çalıştıran örnek. Program adı program.pl olsun.Komut satırından -x seçeneğiyle çalıştırılacak Aşağıdaki satırların tamamı program.pl satırlarının kodlarıdır --------------------------------------------------------------------Bu program bir program içinde perl programi içerir program başlik açiklamasina kadarki satirlari dikkate almaz #!/usr/local/bin/perl print("Merhaba, Ben bir perl programiyim!\n"); __END__ yukardaki satır program sonunu ifade eder. bu satir da dikkate alinmaz.. -------------------------------------------------------------------Çalışması : $ /usr/bin/perl -x program.pl Merhaba, Ben bir perl programiyim! Diğer Seçenekler -u -U -S -D -T -d : core dump oluştur. : Emniyetsiz icra. : Program PATH environment variable'da tanımlı DIR’da. : Dahili debugger flag’larını ekle. : Yazma güvenlik opsiyonu. : Perl debugger kullan. FORMATLI YAZDIRMA Tanımlama: Aşağıdaki tanım basit bir örnektir. format FORMATIM = =================================== B a s k ı F o r m a t ı d ı r =================================== . syntax: format FORMAT_ADI = ------- çıktı satırları ------. BASKI FORMATINI GÖSTERME Bu işlem için iki şeye ihtiyaç vardır. Kullanmak istediğiniz formatı, $~ sistem değişkenine(sistem değişkenlerini göreceğiz), set edin. write fonksiyonunu çağırın. Bununla ilgili bir örnek program görelim. Ör. program: #! /usr/bin/perl $~="FORMATIM"; write; format FORMATIM = ===================== g ö r mek i s t e d i ğ i n i z t e x t ===================== . çalıştır ¿ ===================== g ö r mek i s t e d i ğ i n i z t e x t ===================== İzah: format adı ( FORMATIM ) sistem değişkenine ($~) atandığında perl şunu anlar. write fonksiyonu kullanıldığında atanan format basılacaktır. Son kısımda ise formatın tanımlanması vardır. Not: eğer $~ sistem değişkenine atanma olmasaydı, yazdırma işlemi standart çıktıya (STDOUT) olacak şeklinde algılanacaktı. BASKI FORMATINDA DEĞERLERİ GÖSTERME Tabi ki bu işlemin amacı değişken ve dizilerdeki değerlerin uygun biçimde yazdırılmasıdır. Ör. program:(Sesli harfleri bulur sayar ve basar) 1:#!/usr/local/bin/perl 2: 3: while ($kayit = <STDIN>) { 4: $kayit =~ s/[^aeiou]//g; 5: @sesliler = split(//, $kayit); 6: foreach $sesli (@sesliler) { 7: $seslisayisi{$sesli } += 1; 8: } 9: } 10: $~ = "SESLIFORMAT"; 11: write; 12: 13: format SESLIFORMAT = 14: ========================================================== 15: text içindeki sesli adedi: 16: a: @<<<<< e: @<<<<< 17: $seslisayisi {"a"}, $seslisayisi {"e"} 18: i: @<<<<< o: @<<<<< 19: $seslisayisi {"i"}, $seslisayisi {"o"} 20: u: @<<<<< 21: $seslisayisi {"u"} 22: ========================================================== 23: . çalıştırılır¿ Bu bir sesli harf bulma testidir. Kartal Cimbomu yendi. ^D ========================================================== text içindeki sesli adedi: a: 4 e: 3 i: 6 o: 1 u: 3 ========================================================== çalışması: satır girilir. 4. satırda; a,e,i,o,u dışındakiler elenir 5. satırda; kalanlar(sesli) @sesliler dizisine aktarılır. 6. satırda; sesliler sayılır (@sesliler dizisi test edilerek) ve %seslisayisi bileşik dizisine eklenir. 10. satırda; basım formatı SESLIFORMAT olarak Set edilir. NOT: Değer alanları formatları için tanımlanan değerler hakkında 3 şeyi not etmeliyiz. alanların içerikleri basılır. alan boşluklarını hizalamaya gerek yoktur. alanlar bir üst satırda tanımlı formata uygun tanımlanırlar. DEĞER ALANI FORMATI SEÇİMİ Geçerli değer alanı formatları tablosu Alan Değer Alan Formatı @<<< sola dayalı baskı @>>> sağa dayalı baskı @||| merkeze dayalı baskı @##.## sabit noktalı sayısal baskı @* çok satırlı text Not: @* haricinde tüm tanımlarda alan ölçüsü tanımlı karakter sayısı kadardır. Bu sayıya @ karakteri dahildir. Örneğin; @>>>> tanımı 5 karakter uzunluğu belirtir. Benzer şekilde @##.## uzunluğu 6 dır(. da dahil) ÇOK SATIRLI ALAN FORMATI KULLANIMI Ör prog. #!/usr/local/bin/perl @kayit = <STDIN>; $karakterler = join("",@kayit); $~ = "SATIRLAR"; write; format SATIRLAR = ****** Girdiğiniz dosyanin icindekiler: ****** @* $karakterler ***************************************** . çalıştır: program.pl ¿ ilk satir ikinci satir ucuncu satir ****** Girdiğiniz dosyanin icindekiler: ****** ilk satir ikinci satir ucuncu satir ***************************************** 2. satır file'ın tamamını @input dizisine atar. Her bir satır dizinin bir elemanı olarak yerleşir. 3. satır girilen satırları tek karakter stringi olarak $stringe birleştirerek yerleştirir. Bu karakter stringi newline karakterlerini de içermektedir. 6. satır formatı çağırarak bastırır . @*tanımı çok satırlı text olarak formatlar. DİĞER ÇIKTI DOSYALARINA YAZMA Şu ana kadar write fonksiyonu ile standart çıktı dosyasına yazılma örnekleri gördük. Diğer dosyalara da yazdırabiliriz. En kolayı write'a argüman olarak file'ı geçirmektir. Örneğin DOSYAM ile temsil edilen dosyaya yazmak için (DOSYAM print formatı kullanarak) şu ifadeyi kullanırız; write (DOSYAM); Bu örnekte DOSYAM file adı ve format adı olarak kullanılıyor bu düzenli ve hoştur ama bazı kısıtlamaları vardır. Böyle bir durumda $~ kullanılamaz.(print format seçimi için). $~ sistem değişkeni default file değişkeniyle çalışır. O da write ile çıktıya gönderilir. default file variable'nı değiştirmek böylece $~ da etkin file'ı değiştirmek için hazır select fonksiyonu kullanılır. select (DOSYAM); Select kullanım için default file değişkenini set eder. Örneğin; file değişkeni DOSYAM ile temsil edilen, dosyaya yazmak amacıyla FORMATIM print formatını kullanmak için; select(DOSYAM); $~ = "FORMATIM"; write; kodlamak gerekir. Bu kodlama ile FORMATIM formatı DOSYAM değişkeni ile birleştirilmiş oldu. Bundan sonra write artık bu dosyaya yazdırmaya başlar. Eğer tekrar standart çıktıya yazdırmak istersek select(STDOUT); komutunu kodlarız. Not: select kullanımı sadece write ' a değil print ' e de etki eder. Select fonksiyonu çok kullanışlı olup aynı altyordamla aynı anda birden fazla dosyaya yazdırma imkanı sağlar. Örnek programda bunu görebiliriz. 1: #!/usr/local/bin/perl 2: 3: open (DOSYA1, ">dosya1"); 4: $karakterler = "Denemeler"; 5: select (DOSYA1); 6: &kayityaz; 7: select (STDOUT); 8: &kayityaz; 9: close (DOSYA1); 10: 11: sub kayityaz { 12: $~ = "KAYITYAZ"; 13: write; 14: } 15: 16: format KAYITYAZ = 17: CIKTI DOSYALARIMA@<<<<< YAZIYORUM. 18: $karakterler 19: . çalışması: program.pl¿ CIKTI DOSYALARIMADeneme YAZIYORUM. Yukardaki satır hem ekrana hem de dosya1 isimli dosyaya yazar. Not: select ve $~ rastgele kullanılmaz format takibini kaybedebiliriz. Aşağıdaki örnekteki gibi kullanım uygundur . select (DOSYAM); $~ = "FORMATIM"; write; DEFAULT FİLE DEĞİŞKENİNİ SAKLAMAK (SAVE) . Select son seçilen file değişkeninin içeriğini tutar. Örneğin; $eskidosya = select(YENIDOSYA); select ($eskidosya); şeklindeki kullanımla da önceki dosya lazım olduğunda kullanılabilir. Select ile seçim işini bir alt programla yapar ve programın geri kalanını etkilemede kullanabilirsiniz. Aşağıdaki örneği bu amaçla kullanabilirsiniz, inceleyin. sub standarta_yaz { local ($dosyasakla, $formatsakla); $dosyasakla = select(STDOUT); $formatsakla = $~; $~ = "FORMATIM"; write; $~ = $formatsakla; select($dosyasakla); } Bu alt program default olarak STDOUT set etmek için select'i çağırır. select'in dönüş değeri önceki default file' dır ve $dosyasakla içine saklanmıştır. Sonraki adım STDOUT' a yazmak için kullanılan printformatı save etmektir. Altyordam bunu, $~ halihazırdaki değerini $formatsakla değişkenine saklayarak yapar ve sonra altprogram, FORMATIM 'ı printformatı olarak set eder..(o an kullanımda olacak printformat olarak) write çağrıldığında artık standart output dosyasına FORMATIM formatını kullanarak yazar. Birinci adım; $~' i $formatsakla içindeki değere resetlemek, son adımda $dosyasakla içindeki file' ı default output olarak set etmektir. SAYFA BAŞLIK AYARI dosyaadı_TOP örnek: format STDOUT_TOP = Ertanlar Kollektif Şirketi . yukarıda tanımdaki format her sayfa başına yazacaktır. Bu alanda değişkenlerde kullanılabilir(diğer format tanımlarında olduğu gibi) sayfa başlarına yazılan sayfa numaralarını sistem değişkeni olan $% tutar. örnek: format STDOUT_TOP = Sayfa @<<. $% . bu tanımla mesela 1.sayfa basılırken sayfanın üzerindeki baskı şöyle çıkar. Sayfa 1. BAŞLIK BASKI FORMATINI DEĞİŞTİRME Bu işlem için $^ sistem değişkeni kullanılır. $~ de olduğu gibi default file değeri değişir. Örneğin; başlık formatı olarak BASLIGIM baskı formatını ve başlık file ' ı olarak ta DOSYAM ' ı kullanmak için şu ifadeleri ekleriz. $eskidosya = select(DOSYAM); $^ = "BASLIGIM"; select($eskidosya); . SAYFA UZUNLUĞU ARALIĞI Bu iş için $= sistem değişkeni kullanılır. Default değer 60 satırdır. Mesela 66 satıra ayarlamak için şöyle yazarız. $= = 66; bu atama ilk write' dan önce yapılmalıdır.sayfa ortasında böyle bir ayar yapılırsa sonraki sayfadan geçerli olur. Baskı ve uzunluk ayarı ve formatı kullanan program örneği aşağıdadır. Ör11.08 1: #!/usr/local/bin/perl 2: 3: open (BASKI, ">dosya.dat"); #çıktı file' ı tanımlandı. 4: select (BASKI); 5: $~ = "SATIRYAZ"; #içermez. #çıktı formatı(OUTFILE için) bu atama sayfa başlığını 6: $^ = "TOP_OF_PAGE"; 7: $= = 60; #OUTFILE için satır başlığı formatı belirlendi. #satır ayarı 60 olarak belirlendi. 8: while ($satir = <STDIN>) { 9: write; 10: } 11: close (BASKI); 12: 13: format TOP_OF_PAGE = 14: - sayfa @< 15: $% 16: . 17: format SATIRYAZ = 18: @>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 19: $satir 20: . çalışması: program.pl ¿ bu bir satirdir bu ise ikinci satirdir son satir da bu olsun bakalim. ^D $ more dosya.dat (dosya.dat içeriğini görelim) - sayfa 1 bu bir satirdir bu ise ikinci satirdir son satir da bu olsun bakalim. UZUN KARAKTER STRİNGLERİN FORMATI @* multiline text karakteri ile çok satırı alt alta yazdırmıştık ama bunda formatlama yoktu. Düzgün basım formatı için başlangıçtaki @ yerine ^ karakteri kullanırız. Örnek :program.pl 1: #!/usr/local/bin/perl 2: 3: $string = "Bu\ndengesiz satır\nörneğidir.\n"; 4: $~ = "OUTLINE"; 5: write; 6: 7: format OUTLINE = 8: ^<<<<<<<<<<<<<<<<<<<<<<<<<<< 9: $string 10: . çalışması: program.pl ¿ Bu dengesiz satır Not: 8.satırda ^ yerine @^kullanılsaydı çıktı şöyle olurdu. Bu dengesiz satır örneğidir. Şimdi çok satırlı, formatlı bir örnek görelim. Örnek:program.pl 1: #!/usr/local/bin/perl 2: 3: @aktarma = <STDIN>; 4: $aktarma = join("",@aktarma); 5: $~ = "ALINTI"; 6: write; 7: 8: format ALINTI = 9: Günün sözü: 10: ----------------------------11: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 12: $aktarma 13: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 14: $aktarma 15: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 16: $aktarma 17: ----------------------------18: . çalışması: program.pl ¿ Etkin bir programlama dili programcinin eli ayagidir sihirli bir asadir. ^D Günün sözü: ----------------------------Etkin bir programlama dili programcinin eli ayagidir sihirli bir asadir. ----------------------------- FORMATLAMA ANINDA BOŞ SATIRLARI ELEMEK Bu işlev için yukardaki örnekteki 11,13,15. satırların en başına ~ karakteri konur.Diğer kısımlar aynıdır. 11: ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 12: $aktarma 13: ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 14: $aktarma 15: ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 16: $aktarma BELİRSİZ SAYIDA SATIR GİRMEK. Bunun içinde ~~ sembolü kullanılır. 1: #!/usr/local/bin/perl 2: 3: @aktarma = <STDIN>; 4: $aktarma = join("", @aktarma); 5: $~ = "ALINTI"; 6: write; 7: 8: format ALINTI = 9: Günün Notu : 10: ----------------------------11: ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 12: $aktarma 13: ----------------------------14: . çalışması: ¿ bir başarılı proglamlama dili iyi dizayn edilmişse büyüden farksızdır. ^D Günün Notu : ---------------------------bir başarılı programlama dili iyi dizayn edilmişse büyüden farksızdır. ----------------------------- ÇIKTI FORMATLAMADA printf Aşağıdaki argümanlar printf ' ye geçirilir. a) Bir veya fazla alan tanımlayıcı içeren basılacak string b)Basılacak string de görülecek her alan için bir değer. Alan tanımlayıcıları tablosu aşağıdadır. % işaretiyle kullanılırlar. %c tek karakter %d 10 tabanlı integer %e bilimsel floating-point %f floating-point (sabit noktalı) %g floating-point (birleşik format) %o oktal tamsayı (integer) %s string %u işaretsiz tamsayı %x 16 tabanlı integer Örn: printf("Bastırmak istediğim sayı : %d.\n", $toplam); printf ' ile ilgili bazı özellikler eğer d,o,u,x önüne l (le) koyarsak Long anlamındadır(uzun integer) %ld gibi... bu durum integer çok rakamlıysa kullanılmalıdır. pozitif tamsayı uzunluk gösterir. Örneğin; %20s ifadesi 20 karakter uzunluğunda string anlamındadır. Ve sağa dayalı yerleşir. eğer negatif sayı ile verilirse alan dolmadığında sola dayalı yerleşir. Örneğin; %-20s sola dayalı 20 karakter (alan dolmazsa) eğer e,f,g kullanıyorsak noktadan sonraki hane sayısını verebiliriz. Şöyleki; %8.3f alan genişliği nokta sonrası Not: eğer rakam fazla girilmişse yuvarlama yapılır. Örneğin; Tanım değer %5.2f 43.499 girilmişse değer 43.50 olur. Şu örnekte; %15.10s ise String 15 karakter uzunluğunda bir alana basılacak ama stringin kendisi en fazla 10 karakter uzunluğunda olacak ifadesi vardır. (bu durum basılacak alanda 5 tane boşluk garanti eder). Not: printf ile diğer dosyalara da write ' da olduğu gibi yazma işlemi yapılır. printf DOSYAM ("Toplam: %d.\n", $toplam); SİSTEM DEĞİŞKENLERİ Perl de işlemleri kolaylaştıran çok sayıda sistem değişkeni vardır.Biz bunlardan çok kullanılan bir bölümünü inceleyeceğiz. 1) Genel skalar sistem değişkenleri 2) Pattern sistem değişkenleri 3) Dosya sistem değişkenleri 4) Dizi sistem değişkenleri 5) Hazır dosya (built-in) sistem değişkenleri 1-) GENEL SKALAR DEĞİŞKENLER : Programın gövde kısmında yaratılırlar. Skalar değişken davranışı gösterirler. Bunlar sadece bir değer depolarlar ve programda sadece bir kopyası tanımlanabilir. $_ $_ : Default skalar değişkendir. En sık kullanılandır.En son bulunan örneği içerir. Aşağıdaki fonksiyon ve operatörler $_ ile default olarak çalışırlar. Pattern bulma operatörleri Yerine koyma Çeviri(translate) <> operatörü (eğer for ve while ile kullanılırsa) Chop fonksiyonu Print fonksiyonu Study fonksiyonu a) Pattern Bulma Operatörü ve $_ : Normalde pattern bulma operatörü depolanmış(değişkende) veriyi =~ veya !~ ile test eder. Örnek : print ("merhaba") if ($val =~ /abc/); gibi... default olarak pattern bulma operatörü $_ da depolu veriyi test eder. Bu demektir ki $_ ile =~ operatörüne gerek yoktur. Yani; print ("merhaba") if ($_ =~ /abc/); yerine (ki bu da doğrudur) print ("merhaba") if (/abc/); yazabiliriz. Not : Eğer !~ (pattern bulunamassa doğru) operatörü kullanmak istersek onu $_ ile test ederken bile. açıkça tanımlamalıyız print ("merhaba") if ($_ !~ /abc/); $_, string ve pattern işlemlerinde de kullanılır. $_ = "Stringin içerdigi sayi 25.11."; @array = /-?(\d+)\.?(\d+)/; ikinci ifadede gösterilen, her bir parantezle çevrili altpatern dizinin bir elemanı olduğundan. Sonuçta @array’a (25.11) atanır. b) Yerine Koyma Operatörü ve $_ $val =~ s/abc/def/; ifadelerinde $val içinde abc aranır ve def onun yerine konur. Yerine konmuş operatörü de $_değişkenini kullanır (eğer =~ kullanarak bir değişken tanımlamamışsanız.) Örnek : Aşağıdaki ifade, ilk bulduğu abc’yi $_içinde def ile değiştirir. s/abc/def/; benzer şekilde aşağıdaki ifade $_ içindeki tüm white space space,tab,newline)tek space ile değiştirir. /\s+/ /g; eğer örneklerimizdeki abc ile def yerine koymalarının kaç defa olduğunu bir değişkende tutmak istersek $sayı = s/abc/def/g; kodunu yazmamız yeterlidir. c) Çeviri Operatörü ve $_ Diğerleri gibidir mesela, $_ içindeki küçük harfleri büyüğe çevirmek için tr/a-z/AZ/; yeterlidir. Çevirim sayısını elde etmek istersek $sayı = tr/a-z/A-Z/; kullanırız. Örnek program : tr kullanımını sağlayan program.Program adı program.pl ,içersinde karakterlerin(boşluk hariç) sayılacağı data dosyası ise dosya.dat olsun. #!/usr/local/bin/perl print ("Saymak istediğiniz karakterleri giriniz:\n"); $stringsay = <STDIN>; chop ($stringsay); @karakterler = split (/\s*/, $stringsay); while ($giris = <>) { $_ = $giris; foreach $karakter (@karakterler) { eval ("\$say = tr/$karakter/$karakter/;"); $say{$karakter} += $say; } } foreach $karakter (sort (@karakterler)) { print ("$karakter : $say{$karakter} adettir\n"); } Çalışması : program.pl dosya.dat Saymak istediğiniz karakterleri giriniz: et e : 9 adettir t : 6 adettir d) <> operatörü ve $_ : Yukardaki örnek programda gördüğünüz gibi programın giriş satırını $giris skalar değişkenine okuyup onuda $_ a atıyordu. Bunun daha kısa yolu vardır. while ($giris = <>) { $_ = $giris; ..... ........ } yerine aşağıdaki kodu kullanmak while (<>) { ..... ........ } while ve for döngülerinde <> operatörünün kullanımı tüm girişleri otomatikman $_’a atar. Örnek program : #!/usr/local/bin/perl while (<>) { ($ilkkarakter) = split (//, $_); chop($_); print ("$_ ifadesinin ilk karakteri:\t$ilkkarakter\n"); } Çalışması : program pl Turkiye Cumhuriyeti Turkiye Cumhuriyeti ifadesinin ilk karakteri: T bu bu ifadesinin ilk karakteri: b ^D Not : <> operatörü $_’a atamayı sadece, eğer döngüde bir koşul ifadesi durumunda ise gerçekleştirir. e) Chop Fonksiyonu ve $_ : Default olarak chop fonksiyonu, $_ değişkeni üzerinde işlem yapar ve $_ içindeki değerin son karakteri chop tarafından silinir Yukardaki örnek programda chop($_); ifadesi yerine chop; ifadesi de kullanılabilirdi. while (<>) { chop; ...... } f) Print Fonksiyonu ve $_ : print’de $_’ı default kullanır. Print; satırında $_ içeriği standart output’a yazılır. Örnek program : #! /usr/local/bin/perl print while (<>); Burada giriş satırını okumak için <> operatörü kullanılır ve o satır $_’a kaydedilir. Eğer satır boş değilse(klavyeden girilen satır da olabilir dosyadan okunan da) print fonksiyonu ile $_ içindeki o satır (klavyeden girdigimiz veya dosya adı verilmisse o dosyanın satırları) ekrana yazılır. Çalışması : A) $ program.pl dosya.dat bu satır dosya.dat ın ilk satırı. bu satır dosya.dat ın ikinci satırı.. $ B) $ program.pl Bu satır ekrandan girildi Bu satır ekrandan girildi ^D $ Not : Bu default kullanım standart output için geçerlidir. Başka bir çıktıya yollanacaksa belirtilmelidir. Mesela $ içeriğini DOSYAM’a yazılacaksa print DOSYAM($_) komutu geçerlidir. $_ değişkenin diğer yararları : Bir çok şeyi perl’de pratik yapmamızı sağlar. Mesela aşağıdaki örnekte –e kullanarak dosya1 ve dosya2 içeriği gösterilir. $ perl -e "print while <>;" dosya1 dosya2 benzer şekilde dosya1 ve dosya2 içindeki mum ları nar yapar $ perl –ipe "s/mum/nar/g" dosya1 dosya2 $0 $0 : Program adı değişkenidir. Çalıştırdığınız programın adını içerir. Mesela çalıştırdığınız programın adı prog1 ise; print ("Calısan program $0...\n"); ekrana; Calısan program prog1... yazar. Diğer programları çağıran bir program yazıyorsanız $0 değişkeni çok yararlıdır.Hata oluşursa siz hangi programın hata verdiğini anlayabilirsiniz. die ("$0: dosyası acılamadı\n"); Not: Hatanın tam olarak nerede olduğunu bulmak istiyorsanız sondaki \n karakterini kaldırmalısınız. $< ve $> Kullanıcı Kimliği (User ID) Değişkenleri $< gerçek userID $> etkin userID Gerçek userID programın bağlı olduğu userID dır, etkin userID ise söz konusu olan bir programa birleştirilen ID dir ki her zaman gerçek kullanıcı olmayabilir. Bu değişkenler UNIX sistemindeki perl için geçerlidir. Örnek : #!/usr/local/bin/perl ($kullanici) = getpwuid($<); ($kullanici1) = getpwuid($>); print ("Merhaba Gercek kullanici, $kullanici!\n"); print ("Merhaba Etkin kullanıcı, $kullanici1!\n"); Çalışması; program.pl Merhaba Gercek kullanici, ertan! Merhaba Etkin kullanıcı, ertan! $ $( ve $) Grup Kimliği (group ID) Değişkenleri $( gerçek group ID $) etkin grup ID Bir önceki değişkenlere benzer özellikler bunlar içinde sözkonusudur.Sadece user yerine grup ifadesi geçerlidir. $] $] : Perl version numarası değişkenidir. Örnek : #!/usr/local/bin/perl $] =~ /Revision: ([0-9.]+)/; $revision = $1; $] =~ /Patch level: ([0-9]+)/; $patchlevel = $1; print ("revision $revision, patch level $patchlevel\n"); Çalışması; $ program.pl $ revision 4.0.1.8, patch level 36 $ $/ $/ : Giriş satırı ayıracı değişkenidir. Perl’de giriş anında bir satır karakter karakter okunur. Satır sonu \n ile anlaşılır. \n bir ayraç karakteri olarak düşünülebilir. İşte bu değişken kullanılarak ayraç karakterleri belirlenebilir, değiştirilebilir. Mesela $/’a null karakteri set edilirse, perl inputline ayracı olarak 2 adet \n karakteri var sayar. Örnek : #!/usr/local/bin/perl # Bu programda giriş yapılırken : karakteri son karakter olarak kabul edilir # diğer karakterler dikkate alınmaz $/ = ":"; $satir = <STDIN>; print ("$satir\n"); Çalışması; $ program.pl Bu satir sonu ayrac denemesidir: Bu karakterler dikkate alinmayacak. Bu satir sonu ayrac denemesidir: $ $\ $\ : Çıktı satırı ayırac değişkenidir. Bu değişkendeki karakter her print den sonra otomatikman bastırılır. Bu değişkende değişiklik yapacaksak - l seçeneği seçilir. Örnek : #!/usr/local/bin/perl $\ = "\n"; print ("Bu ilk satir."); print ("Bu da ikinci."); $\ = "\t"; print ("Bu ucuncu satir."); print ("Dorduncu satir."); Çalışması; $ program.pl Bu ilk satir. Bu da ikinci. Bu ucuncu satir. Dorduncu satir. $ $, $, : Çıktı için alan ayıracı değişkenidir. Bu değişken, print çağrıldığında basılacak elemanlar arasına konacak karakter(ler)i tutar. Örnek : print ($a, $b); kodu ile print önce $a’ı basar sonra $, içeriğini en son $b’yi basar. Örnek : #!/usr/local/bin/perl $a = "Merhaba"; $b = "Ertan"; $, = " "; #alan ayracı olarak bosluk(null) atanıyor. $\ = "\n"; #sonlandırma ayracı ise yeni satır karakteri. print ($a, $b); Çalışması; $ program.pl Merhaba Ertan $ $” $” : Dizi elemanları ayıracı değişkenidir. Örnek : #!/usr/local/bin/perl $" = "::"; @meyva = ("Elma", "Armut", "Muz", "Nar"); print ("@meyva\n"); Çalışması; $ program.pl Elma::Armut::Muz::Nar $ $# $# : Sayı çıktısı formatıdır. Bu değişken sadece Perl5 için geçerlidir. Normalde print fonksiyonu 20 rakam float point çıktı basma ayarına sahiptir. Yani; print($x); ile printf ("%.20g", $x); aynıdır. Default formatı değiştirmek için $# değeri değiştirmelidir. Mesela hassasiyetin 15 rakam olmasını istiyorsak; $# = "%.15g"; kodu yeterlidir. Görüldüğü gibi cins tanımlayıcı da tanımlanır. Tıpki printf ve sprintf’deki gibi. Yalnız bu değişkenin kullanımı pek tavsiye edilmemektedir. $#diziAdı $#diziAdı : Bu değişken dizinin son elemanının indisini tutar. Örneğin; @meyva = ("elma", "armut", "nar"); $sonindex= $#meyva; dizi 3 elemanlıdır. 0.eleman, 1.eleman ve 2.eleman.Son elemanın indisi görüldüğü gibi 2 dir. $sonindex içeriği de 2 dir. Eleman indisi belirlemede $[ sistem değişkeninin etkili olduğunu unutmayalım. $[ default değeri 0 dır. Onun için dizinin ilk elemanının indisi 0 dır. Eğer bu değer 1 olursa dizininki de 1 den başlar.Bir $#diziAdı değişkeni her bir hazır dizi değişkenleri içinde tanımlıdır. Örneğin; $#ARGV, komut satırındaki eleman sayılarını tutar. Aşağıdaki örnek $#dizi kullanım örneğidir. #!/usr/local/bin/perl @ornek = ("Yıl",1999,"Ay",12); for ($i = 0; $i <= $#ornek; $i++) { print ("$ornek[$i]\n"); } print ("$ornek[$#ornek]\n"); # son elemanın içeriği basılır (12) çalıştır Yıl 1999 Ay 12 12 $#dizi kullanarak, dizi uzunluğu kontrolü yapılabilir ve bu değişkene istenilen değer atanarak o değer kadar elemanı içerecek şekilde dizi tanımlanabilir. Mesela; @meyva = ("nar", "elma"); @meyva dizisinin son indisi 1 dir(0 ve 1. eleman var). İstersek bu dizinin boyutunu artırabiliriz, değiştirebiliriz. $#meyva = 10; kodu,dizinin son indisinin 10 olduğunu belirler yani dizi 11 elemanlı olmuştur(0-10) Diğer elemanlar boştur. Eğer maximum boyutu azaltırsak geri kalanlar yok olur. $@ $@ : Eval fonksiyonu hata mesajı değişkenidir. Örnek ifade : eval ("die (\"Bir sey olmadi\")"); ise bu satırda mesaj, $@ 'a atanır. Hata oluşursa Bir sey olmadi at(eval) line1. gibi bir mesaj verir. $@ değişkeni ayrıca require fonksiyonu ile oluşan hata mesajını döndürür. $? $? : Sistem hata kodu değişkenidir. Hata durumunu döndürür. $! $!: Sistem hata mesajı değişkenidir. C dilindeki errno değişkeni ile aynıdır. $. $. : Bulunulan satır numarası değişkenidir. Mesela bir dosyadan satır okunurken okunmuş olan son satırın numarasını içerir. Örnek : #!/usr/local/bin/perl open (DOSYA1, "dosya.dat") || die ("dosya.dat açılamadı\n"); open (DOSYA2, "dosya2.dat") || die ("dosya2.dat açılamadı\n"); $input = < DOSYA1>; $input = < DOSYA1>; print ("Satır numarası $.\n"); $input = < DOSYA2>; print ("Satır numarası $.\n"); $input = < DOSYA1>; print ("Satır numarası $.\n"); Çalışması; $ program.pl Satır numarası 2 Satır numarası 1 Satır numarası 3 $ $* $* : Çok satırlı izleme (bulma) değişkenidir. Aslında patern aramalar tek satır gibi düşünülür. Ama çok satır varsa (text in tamamının içerisinde \n karakterleri vardır demektir) Sistem değişkeni $* içerisine 1 atanır. (default 0 ayarlanırsa çok satırlı pattern araması istenmiyor demektir ) $[ $[ : Dizinin 1. elemanının indisini tutan değişkendir. Default’u 0 olduğu için dizilerde 1. indis 0’dır. Eğer uygulama kolaylığı olsun diye 0 değil 1 yapmak istersek; Örneğin : 1.. $[ = 1; 2.. @meyva = ("nar", "muz", "kivi", "dut"); 3.. $ilk = $ meyva[1]; kodlaması sonucu $ilk içeriği nar’dır Yani meyva dizisinin 1 nolu indisine (ikinci elemanı) atama yapılmıştır.1.satırdaki tanım yapılmasa idi meyva dizisinin 0 nolu indisine yani ilk elemanına atanacaktı. Bu değişkende perl5’e aittir ve değiştirilmemesi (yani 0 kalması) iyi olur. $; $; : Çok boyutlu bileşik dizilerde indis(subscript) ayracı vazifesi gorur. Örneğin : Perlde; $degisken = $dizi{" nar "}{" bar "}; ifadesi geçersizdir. 2 boyutlu dizi yoktur. Bu tip diziye erişimi inceleyelim ; $degisken = $dizi " nar "," bar "}; perl bu ifadeyi görünce onu şu şekle dönüştürür. $degisken = $dizi{" nar " . $; . " bar "}; $; değişkeni indis ayıracını tutar, otomatikman virgül koyarak iki dizi indisini ayırır. Başka bir kullanım örneği :Alttaki iki satır da aynı işlevi yerine getirirler. $degisken = $dizi{"Ali", 4, "merhaba"}; $degisken = $dizi{"Ali".$;.4.$;."merhaba"}; ikinci satır $; değerinin(virgül) indislerin arasına girerek ayırdığını gösterir. $; değişkeninin default değeri \034 (Ctrl+\)’dir. Bunu isterseniz başka bir değere tanımlayabilirsiniz. $;’ın set edilmesi ile ilgili Örnek : #!/usr/local/bin/perl $; = "::"; $array{"Ertan","No"} = 46; $bir = $array{"Ertan","No"}; $iki = $array{"Ertan::No"}; print ("$bir, $iki\n"); Çalışması; $ program.pl 46, 46 $ Not : $; içine atanacak değer bir indis olarak kullandığınız karakter olamaz. $: $: : Kelime kesme ayıracıdır. Kelime bölme karakteri default olarak boşluk karakteri, \n karakteri ve – karakteridir. Kabul edilebilir kelime kesme karakterleri $: içinde depolanmıştır. Mesela bir satır belli bir uzunlukta ise ve format biçimi kısa ise uzun olanlar kesme karakterinde sonra dikkate alınmazlar. Örneğin : Bu bir deneme satırıdır ^<<<<<<<<< Çıktı; (satır) (format) bu bir Olur. 2. boşluktan sonraki kelime formattan uzun olduğu için dikkate alınmaz. Boşluk kelime ayıracıdır, oradan kesilmiştir. Değerini değiştirebilirsiniz.( $: = " \n";) gibi... $$ $$ : Perl yorumlayıcının prosesinin ID si (program proses ID’si aynı zamanda) değişkenidir. $ARGV $ARGV : En son kullanılan dosya adını tutar.<> ile file dan ilk okutulduğunda file’ın adını $ARGV tutar. Buradan o an için kullanılan dosya bilinir. Örnek : #!/usr/local/bin/perl print ("Aratacaginiz stringi giriniz:\n"); $string = <STDIN>; chop ($string); # program adıyla birlikte komut satırından while ($dosyaal = <>) { # verilen dosya isimlerini alır if ($dosyaal =~ /$string/) { print ("$ARGV:$dosyaal"); } } Çalışması; $ program.pl dosya.dat dosya2.dat dosya3.dat Aratacaginiz stringi giriniz: test dosya.dat:Bu bir test dosyasıdır. dosya3.dat:Bu bir test islemidir $ $^W : İkaz mesajı basılıp basılmayacağını tutar 0 ise kapalıdır. 1 ile mesajı açar. $^X : Bu değişken programı komut satırından başlatırken ilk kelimeyi tutar. Programın adı ile başlamışsanız bu değişkende program adı vardır. Örnek : if ($^X ne "perl") { print ("Programa başlarken \n"); print ("’Perl’ komutunu kullanmadınız"); } 2-) PATERN SİSTEM DEĞİŞKENLERİ : Şu ana kadar gördüğümüz sistem değişkenleri program içinde tanımlanmışlardır. Bundan sonrakiler sadece çalıştığınız ifade bloğunda tanımlıdırlar. (Bir ifade bloğu {} karakteri ile çevrelenmiştir.) Patern sistem değişkenleri, patern bulma operatörleri ve patern kullanan diğer operatörleri set eder. Bulunan Patern’i Tekrar Elde Etme Patern bulma veya yerine koyma operatörü için patern tanımladığımızda patern kısmı parantezle çevrelenir. Örnek : /(\d+)\./ patterni, \d+ alt paternini parantezle çevreler. Bu parantezler tabii ki patternin parçası değildirler ve bu alt pattern 1 veya fazla rakam bulma örneğidir. Bir pattern bulunduktan sonra sistem değişkenleri onları tutar $1,$2 gibi.. Örneğin, aşağıdaki pattern başarıyla bulunduysa. /(\d+)([a-z]+)/ bu durumda bulunan örnek 1 veya fazla rakam ve bir veya fazla küçük harf karakteri olmalıdır. Bu taktirde $1 içeriği : 1 veya fazla rakam $2 içeriği : 1 veya fazla küçük harften oluşur. Örnek : dosya.dat içeriği şöyle olsun; 45 45**32 34.57 10.5e+12 445/14 5**32 39.57 + 18 programımız; #!/usr/local/bin/perl while (<>) { while (/(-?\d+)\.(\d+)([eE][+-]?\d+)?/g) { print ("Tamsayı kısım $1, Ondalık kısım $2"); if ($3 ne "") { print (", exponent $3"); } print ("\n"); } } Çalışması; $ program.pl dosya.dat Tamsayı kısım 34, Ondalık kısım 57 Tamsayı kısım 10, Ondalık kısım 5, exponent e+12 Tamsayı kısım 39, Ondalık kısım 57 $ dikkat, $1 yerine 1. bulunan için $0 kullanmayınız. Biliyorsunuz $0 program adını tutar. * Önceki konularda işlenen \1,\2,\3 ....ile $1’i karıştırmayınız sadece pattern içinde tanımlıdırlar. Parantezlerin sayımı soldan başlar ilk bulunan $1’e konur. Şu örnekte /(\d+(\.)?\d+)/ seçenek olarak decimal noktası içerebilen bir veya fazla rakam bulunur. Dolayısıyla pattern tümüyle tek bir değeri (parantezi) temsil eder. Tümüyle sonuç $1’dedir. $& $& : Patern’in Tamamını Elde Etme Patern başarıyla bulunduğunda bulunan text string sistem değişkeni olan $& de saklanır. Bu bulunan patterni elde etme yoludur. Çünkü, patern bulucu true veya false döndürür. (paternin bulunmasının başarılı olup olmadığı) tabi bunun dışında paterni elde etmenin bir yolu daha vardır. Paternin tamamını parantezle çevreler ve $1 değerini kontrol edersiniz ama $&’den elde etme yolu daha kolaydır. Aşağıdaki program $& kullanarak giriş dosyası içindeki tüm rakamları sayar. Örnek : #!/usr/local/bin/perl while ($dosyaadi = <>) { while ($dosyaadi =~ /\d/g) { $rakamsay[$&]++; } } print ("Her bir rakam için toplam:\n"); for ($i = 0; $i <= 9; $i++) { print ("$i: $rakamsay[$i]\n"); } Çalışması; $ program.pl dosya.dat Her bir rakam için toplam: 0: 1 1: 4 2: 4 3: 4 4: 6 5: 7 6: 7: 2 8: 9: 1 $ Bu program bir anda 1 satır okur(komut satırında verilen dosyadan). 3.satır giriş satırından her bir değişkeni bulur. Bulunan rakamlar $&’a depolanır. 4. satır $&’ın değerini alır ve onu @rakamsay dizisinin indisi olarak kullanır. Bu dizi her bir rakamdan kaç tane olduğunu sayar ve tutar. Tüm giriş dosyası okunduğunda sonuc basılır. Not : $& değerine ihtiyacınız varsa, while döngüsü içinden veya bulunan patternin olduğu bloktan çıkmadan onu elde ediniz. $` ve $’ Bulunan Stringin Dışındaki text’i Elde Etme Değişkenleri : Pattern bulununca $&’a depolanacağından diğer text stringi ise diğer iki sistem değişkenine atanır. · · · · · Örnekten önceki kısım $` · · · · · Örnekten sonraki kısım $’ a atanır. Örneğin, ertan1234ankara stringinde /\d+/ paterni ile, 1234 bulunur ve $&’a atanır. Rakam öncesi kısım olan ertan, $` , ankara ise $’ değişkenlerine atanır. $+ $+ Değişkeni : Bu değişken, parantezle çevrelenmiş son altpatterni bulur. Örneğin, aşağıdaki pattern’i dikkate alırsak, /(\d+)\.(\d+)/ $+ , ondalık noktası sonrasındaki patterni bulur. Yani $+ içeriğinde . sonrasındaki (\d+) patterni bulunur. Bu değişken çok yararlıdır. 3-) FİLE SİSTEM DEĞİŞKENLERİ : Çeşitli sistem değişkenleri, file(dosya) değişkenleriyle birleştirilmiştir. $~ $~ : Default print format değişkenidir. Bir dosyayı tutar. Bu değişkeni biçimli yazdırma derslerinde de görmüştük. Değiştirmek isterseniz ($~ değerini) aşağıdaki kodu mesela standart output için örnek verebiliriz. select (STDOUT); $~ = "MYFORMAT"; write; write komutu çıktı formatı için MYFORMAT biçimini kullanır. $= $= : Sayfa uzunluğu tanımlar. Select (“uzunluk”); $= = 72; uzunluk dosyası için sayfa uzunluğu 72 olur. Not : Eğer sayfa başlık formatı tanımlanmışsa sayfa uzunluğu default olarak 60 dır. Sayfa başlık formatı (page headerformat) tanımlanmamışsa default sayfa uzunluğu 9999999 dır. Çünki Perl onun sürekli basılacağını varsayar. Eğer çıktı file’ı için başlıksız sayfa tanımı yapmak isterseniz boş sayfa başlığı tanımlayınız. $- $- : Listelenen dosyada artan (kalan) satırların sayısını tutar. Write ile satırlar yazıldıkça $içeriği azalır. 0 olunca yeni sayfaya baslanır. Yeni sayfa başlayınca $= değeri; bu değişkeninde başlangıç değeri olur. Örnek #!/usr/local/bin/perl open (BASKI, ">outfile"); select ("BASKI ); write; # BASKI default olarak set edilir #yeni bir sayfa başlatır print STDOUT ("write öncesi: $-\n"); write; print STDOUT ("write sonrası: $-\n"); format BASKI = Test Baskısıdır. . format BASKI_TOP = Test baslik . Çalışması; program.pl (Ekrana bastıkları) write öncesi : 58 write sonrası: 57 (outfile dosyasına yazdıkları) Test baslik Test Baskisidir. Test Baskisidir. Not: BASKI_TOP formatı olmasaydı Ekrana, write öncesi : 99999999 write sonrası: 99999998 outfile dosyasına ise, Test Baskisidir. Test Baskisidir yazardı. 5. satırda standart output a $- değeri gönderir. Standart output file’ı tanımdan dolayı burda BASKI dır. $^ $^ :Sayfa başlığı formatı değişkenidir. Bu değişkenin tuttuğu sayfa başlığı formatı yoksa sayfa başlığı yoktur. $^ içeriğindeki değer sayfa başlığı formatı adıdır. Sayfa başlığı isminin default’u basılacak dosya adına TOP ilavesi ile oluşur. Önceki örnekte BASKI_TOP buna örnektir Yukardaki örneğe su satırı eklersek, print STDOUT ("baslik: $^"); Satırın ekrana bastığı değer baslik: BASKI_TOP olacaktır. Bu değişkene atama da yapılabilir, Select(DOSYAM); $^=”BASLIK”; ...gibi.. $| $| : Buffer’lama Çıktısı Değişkeni (buffer kullanıldı mı? kullanılmadı mı?) : Bazı sistemlerde, print veya write kullanarak bir file’a çıktı yollandığında sistem ilk önce buffer olarak bilinen bir özel diziye çıktıyı gönderir.Buffer tamamen dolduğunda bir defada dosyaya yazılırlar. Bu çıktı buffer’lama olayıdır. Bazı durumlarda araya buffer sokmaksızın direkt olarak dosyaya yazmak isteyebiliriz. Mesela iki proses standart çıktıya aynı anda gönderilebilir. İşte $| değişkeni belli bir dosyanın bufferlanıp bufferlanmadığını belirler. Default olarak perl her bir çıktı dosyası için bir buffer tanımlar ve $| değişkeni 0’a set edilir. Bir dosya için buffer’ı devreye sokmamak için önce dosya seçilir sonra $| değişkenine 0’dan farklı değer set edilir. Örnek : select ("DOSYAM"); $| = 1; Bu ifade ile default çıktı dosyası olarak DOSYAM seçilir ve onun için bufferlama kapatılır. Bu işlem yazma işleminden önce yapılmalıdır. $% $% :(current) Basılan sayfa değişkeni Perl’de açılan her output dosyası $% değişkeni ile ilişkilendirilir(birleştirilir). Bu değişken o anki sayfa numarasını tutar. Write, yeni bir sayfaya başladığında $%’ın değerine 1 eklenir. Herbir $% kopyasının başlangıç değeri 0’dır. İlk sayfa basıldığında 1’e set edilir. Sayfa Baslığı formatında bu değişken kullanılabilir. 4-) DİZİ SİSTEM DEĞİŞKENLERİ : Şu ana kadar gördüğümüz sistem değişkenleri skalar değişkenlerdir. Bundan sonrakiler dizi değişkenleri olacaktır. Bunlardan @_ değişkeni hariç diğerleri global değişkendir. Değerleri bir program içinde aynıdır. @_ @_ : Alt programlarda tanımlıdır. Alt programa geçirilen argümaları liste halinde tutar. Örneğin; Ana program ........................................... &altprogram("merhaba", 2, $degisken); #altprogram isimli altprogram devreye sokuluyor ..... .... # parentez içindekiler alt programa geçirilen değerlerdir ----Ana program sonu........................................ --Alt program kısmı-----------------------------------sub altprogram { local ($arg1, $arg2, $arg3) = @_; #alt programa gönderilen değerleri bir liste #halinde tutan değişken @_ dir.ve burada ..... #tüm bu değerler sırayla $arg1, $arg2,$arg3 e aktarılır. ....... } Alt program sonu --------------------------------------- Örnek : yukardaki gibi kodlanmış bir ana ve alt program örneğinden hareket edersek, &altprogram("merhaba", 2, $degisken); satırında alt program çağrılır ise alt programa geçirilen parametreler "merhaba", 2, $degisken , @_ içinde tutulurlar ve argüman olarak alt programa geçirilirler. Alt programlarda local tanımı ile skalar değişkenlere (lokal olarak tanımlı) @_ dizisi değişkenleri atanabilirler. @ARGV @ARGV : Perl’de program çalıştırma aşamasında, komut satırından bazı değerleri programa geçirebilirsiniz.Bu değerlerin tutulduğu değişken @ARGV dir. Örneğin ; program.pl ertan 47 Komutyla program.pl çalıştırılırsa, ertan ve 47 değerleri programa aktarılır. İşte bu değerler @ARGV dizisinde saklanırlar. İsterseniz print(“@ARGV\n”); komutu bu değerleri ekrana basar. @ARGV aynı zamanda <> operatörleriyle birleştirilmiştir. Bu operatör, @ARGV içindeki elemanları dosya adı olarak değerlendirilir. Her bir dosya açılır ve sırayla okunur. Eeğer programın ana gövdesinde, alt yordam dışında shift fonkfiyonu çağrılmışsa, ve onunla argüman geçirilmemiş ise, perl @ARGV nin ilk elemanının silindiğini varsayar.Aşağıdaki döngü @ARGV nin her elemanını, dönüşte $degisken içine atar. while ($degisken = shift) { # satırlar } 5-) HAZIR DOSYA DEĞİŞKENLERİ : STDIN, STDOUT ve STDERR STDIN : Default input file’ı tutar. STDIN’i <> operatörü ile kullanırsak normalde keyboard’dan okur. Eğer yönlendirme operatörleri shell den girilmişse, STDIN bir dosyadan okur. STDOUT :Standart output dosyasını tutar bu da ekrandır. Eğer <,> gibi operatörlerle dosyalara yönlendirilmişse o dosya STDOUT dosyası olur. STDEER : Error dosyası olup ekrana ayarlıdır. Diğerlerinde bahsedilenler bunun içinde geçerlidir. Bu hazır değişkenleri open kullanarak diğer dosyalarla birleştirebilirsiniz. (open (STDIN, "inputf"); gibi... Bir dosya değişkenini standart file ile birleştirmek için <STDIN> ile yönlendirmeden sonra dosya adı olarak “-” tanımlayın. Örnek : open (ORNEKSTDOUT, "-"); Bir file değişkenini standart output file ile birleştirmek için filename olarak >- kullanılır. Örnek : open (ORNEKSTDOUT, ">-"); ARGV : ARGV en son kullanılan dosyayı temsil eder. <> operatörü ile o anki okuma yapılan dosya ile birleştirilen özel file değişkenidir. Örnek : $satir = <>; bu ifade ile o an kullanılan dosyadan okuma yapılır. Çünkü ARGV o anki okuma yapılan dosyayı temsil eder. Aşağıdaki kodla aynı şeyi ifade ederler. $satir = <ARGV>; <> operatör yoluyla olması dışında, normalde ARGV’ye erişmeye pek ihtiyaç duymayız. DATA : Bu file değişkeni, özel _END_ değeriyle kullanılır ki bu değer program sonunu belirleyen değerdir.DATA ise _END_ satırından sonraki satırları alır ve kullanır. _END_ ‘den sonra DATA okutulursa size aynı dosyada başka bir program dahil etmenizi sağlar. Daha önce de bir örnek görmüştük. Örnek #!/usr/local/bin/perl $line = <DATA>; print ("$line"); __END__ Bu benim kayıtım. Çalışması; $ program.pl Bu benim kayıtım. $ Programda _END_ program sonunu belirler. 3.satır DATA file dosyasından okur, _END_ den sonraki ilk satır okunur ve $line’a atanır. _ Underscore File Değişkeni : stat fonksiyonu veya file test operatörlerinden birisi ile en son çağrılan file’ı temsil eder. Örneğin ; $readable = -r "/u/public/dosyam"; $writeable = -w _; 2. satırdaki _ karakterinin temsil ettiği file değişkeni "/u/public/dosyam" ı temsil eder. Asıl yararı , birkaç file test operatörü ile kullanıldığında aynı dosya ismini tekrarlamak yerine kullanılır. if (-r "dosyam.dat" || -w _ || -x _) { print ("dosyam.dat dosyasını okuyamam,yazamam veya çalıştıramam.\n"); } ` İLE SİSTEM KOMUTLARINI ÇAĞIRMAK $ben = `whoami`; #whoami komutunu çalıştırır,çıktıyı $ben içine atar. Print $ben; Çıktı: ertan Şöyle de kullanılır; $komut = "whoami"; $ben = `$komut`; print "$ben"; Çıktı: ertan şu kullanımda olur, $ben = qx#whoami#; (qx, string sınır belirleyici olarak tanımladı) print "$ben"; Çıktı: ertan qx ile ilgili not: eğer qx ile string sınır belirleyici karakter ( ise kapama karakteri ( değil, ) olur. Örnek:$kim = qx(whoami); ALT PROGRAMLAR -subroutinAlt programlar fonksiyon veya altyordam olarak da bilinen ve ana programdan çağrılarak devreye sokulan program parçalarıdır.Programların takibi ve anlaşılabilirliği ve kodlama işlemini en aza indirmesi açısından çok yararlıdırlar.Alt programlara ana programdan değer göndermeksizin herhangi bir işlev yürütülebildiği gibi değer gönderilip dönüşte değer de alınabilir.Programın herhangi bir yerinde tanımlanabilirler. Ancak genel kabul gören kullanım programın baş veya son kısımlarında tanımlanmalarıdır. Alt programlar sub ifadesiyle belirtilirler.Ana programdan çağrılacakları zaman ise alt programın adı verilir. Alt program adının başında & karakteri bulunur. Öneklersek,alt program adı yaz ise, çağırma kodu: &yaz dır.Alt program tanım satırı ise En sade şekliyle sub yaz{}; biçimindedir Şimdi örneklerle konuyu daha iyi anlamaya çalışalım. Örnek : Program akış sırası #!/usr/local/bin/perl 1 $toplam = 0; 2 &sayilarial; 3 # bu satıra gelindiğinde alt program devreye girer # alt program satırlarının tamamı icra edildikten sonra # program akışı tekrar buraya döner ve # alt satırdan(foreach ..) devam eder # ana programın son satırı toplam değerin yazdırıldığı # print("Girisi .... satırıdır.İcra burada biter. foreach $sayi (@sayilar){ 8 $toplam += $sayi;} 9 print("Girisi yapilan sayilarin toplami: $toplam \n"); 10 # Burası ana program sonudur sub sayilarial { 4 $degergir=<STDIN>; 5 $degergir =~s/^\s+|\s*\n$//g; 6 @sayilar=split(/\s+/,$degergir); } Çalışması : program.pl 7 2 45 67 89 Girisi yapilan sayilarin toplami: 203 Not:Alt program bir kez tanımlandıktan sonra altprogram çağırmak için baştaki & karakterini Kullanmasak da perl onun alt program olduğunu anlar. Örnek : #!/usr/local/bin/perl sub satiroku { $satir=<STDIN>; } print ("merhaba henuz alt program calismadi\n"); &satiroku; print ("& karakteri kullandigimiz alt program satiri: $satir\n"); satiroku; print ("& karakteri kulanmadan ayni alt program su satiri okudu: $satir\n"); Çalışması : program.pl merhaba henuz alt program calismadi ilk satir & karakteri kullandigimiz alt program satiri: ilk satir ikinci satir & karakteri kulanmadan ayni alt program su satiri okudu: ikinci satir Alt Yordamdan Değer Döndürme : Örnek : #!/usr/local/bin/perl $toplam=0; @sayilar=&sayilarial; foreach $sayi (@sayilar) { $toplam +=$sayi; } print ("Toplam: $toplam\n"); sub sayilarial { $satir=<STDIN>; $satir=~ s/^\s+|\s*\n$//g; split(/\s+/, $satir); #dönüş değeri } Çalışması : program.pl 12 23 34 1 Toplam: 70 Dönüş değerleri daha sonra bir ifade içinde de kullanılabilir. Örneğin : Foreach $sayi (&sayilarial); { Print (“$sayi\n”); } Return Deyimi : Bu deyim alt yordamdan değer döndürmenin bir başka yoludur. Biçimi: return (dönüş_değeri); Örnek : #!/usr/bin/perl $toplam = &toplam_al; if($toplam eq "Hata") { print("Deger alinamadi .\n"); } else { print ("Toplam : $toplam.\n"); } # ana program sonu sub toplam_al { $deger = 0; $gir = <STDIN>; $gir =~ s/^\s+|\s*\n$//g; if ($gir eq "") { return ("Hata"); } @alt_kelimeler = split(/\s+/, $gir); $indeks = 0; while ($alt_kelimeler[$indeks] ne ""){ $deger += $alt_kelimeler[$indeks++]; } $donus_degeri=$deger; # $donus_degeri içeriği ana programda # $toplam içine aktarılacak } # alt program sonu Çalışması : program.pl 12 23 Toplam : 35. program.pl ^D Deger alinamadi . my() ve local() hazir fonksiyonları kullanımı: Bu fonksiyonlar alt programlarda kullanılır ve sınırlı kullanım alanı olan değişken yaratırlar.Parantez içinde ifade edilen bu değişkenlerin kullanımlarını inceleyecek olursak, My() ile oluşturulup kullanılan değişkenleri sadece ait olduğu alt programlar kullanır atama yapabilirler.Çalışma suresince değişken içeriği bu alt programda aynı kalır. local() ise o alt Program tarafından çağrılan diğer alt programda da kullanılabilir.Konuyu anlamak için aşağıdaki programın çalışmasını incelemeniz yararlı olacaktır. Örnek: #!/usr/bin/perl ilk_alt_program("Ertan", "Bertan"); sub ilk_alt_program { local ($degisken1) = $_[0]; # "Ertan" atanıyor my($degisken2) = $_[1]; # "Bertan" atanıyor print("ilk_alt_program: degisken1 = $degisken1\n"); print("ilk_alt_program: degisken2 = $degisken2\n\n"); ikinci_alt_program(); print("ilk_alt_program: degisken1 = $degisken1\n"); print("ilk_alt_program: degisken2 = $degisken2\n\n"); } sub ikinci_alt_program { print("ikinci_alt_program: degisken1 = $degisken1\n"); print("ikinci_alt_program: degisken2 = $degisken2\n\n"); $degisken1 = "Ahmet"; $degisken2 = "Mehmet"; print("ikinci_alt_program: degisken1 = $degisken1\n"); print("ikinci_alt_program: degisken2 = $degisken2\n\n"); } Çalışması: program.pl ilk_alt_program: degisken1 = Ertan ilk_alt_program: degisken2 = Bertan ikinci_alt_program: degisken1 = Ertan ikinci_alt_program: degisken2 = ikinci_alt_program: degisken1 = Ahmet ikinci_alt_program: degisken2 = Mehmet ilk_alt_program: degisken1 = Ahmet ilk_alt_program: degisken2 = Bertan ALT PROGRAMLARDA @_ KULLANIMI: @_ sistem dizi değişkeni alt programlarda kullanılır ve ana programdan gelen değerleri(parametreleri) içerir.Perl programlarında çok sık kullanılır. @_ içeriği aslında yukardaki örnekte gördüğümüz $_[0] , $_[1] değişkenlerini içeren bir sistem dizi değişkenidir.Bu durumu çok iyi gösteren aşağıdaki programı inceleyiniz. Örnek program: #!/usr/bin/perl print ("Ana program basladı.Henüz alt program devrede değil\n"); ilk_alt_program("Ertan", "Bertan"."Ahmet"); print ("Alt programdan dönüldü...Program sonu !\n"); sub ilk_alt_program { print ("Şimdi alt programdayiz ve ana programdan gelen değerler aşağıda\n"); local ($a1,$a2,$a3) = @_; print("$a1,$a2,$a3\n"); print("$_[0],$_[1],$_[2]. \n"); Çalışması : program.pl Ana program basladı.Henüz alt program devrede değil Şimdi alt programdayiz ve ana programdan gelen değerler aşağıda Ertan,BertanAhmet, Ertan,BertanAhmet,. Alt programdan dönüldü...Program sonu ! Bir başka örnek program: #!/usr/local/bin/perl parametre_say(1, 2, 3, 4, 5, 6); parametre_say("A".."Z"); sub parametre_say { $parametre_adedi = @_ ; print("Parametre Adedi: $parametre_adedi\n"); CALIŞMASI: program.pl Parametre Adedi: 6 Parametre Adedi: 26 DOSYALAR - 2 - Dosya giriş çıkış fonksiyonları Temel giriş çıkış fonksiyonları open, close, print, printf, write fonksiyonlarıdır. Bunları görmüştük . Hatırlayalım ve biraz daha inceleyelim. Open Fonksiyonu : Dosya erişimi sağlar. open (DOSYAM, "/u/ertan/dosya.txt"); open, default olarak okuma amaçlı dosya açar.İlk defa açılan dosyaya yazmak için > kullanılır. open (DOSYAM, ">/u/ertan/dosya.txt"); Mevcut dosyaya eklemek için ise >> kullanılır; open (DOSYAM, ">>/u/ertan/dosya.txt"); Ayrıca open (MAIL, "|mail ertan"); şeklinde pipe ile kullanımını da görmüştük. open fonksiyonu bunlardan başka daha birkaç çeşit dosya açma biçimi kullanır. Aşağıdaki kullanım bunlardan birisidir. open (CAT, "cat dosya*|"); burada open, unix'teki cat dosya* komutunu icra eder. | işareti dosya adından sonra yazılır. Buradaki komutla adı dosya ile başlayan tüm dosya isimleri bir dosyaya listelenir. Bu dosya bir giriş dosyası gibidir ve CAT dosya değişkeni kullanılarak erişilebilir. Örnek : pipe'lı komutla unix'teki w komutu çıktısını giriş olarak alma Not: w komutu çıktısını aşağıda görüyorsunuz.Programı ona göre inceleyiniz. ertan> w 11:09am up 30 days, 2:31, 3 users, load average: 0.06, 0.07, 0.01 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT ftpadmin ttyp3 darkness.anadolu Wed 1pm 12:22m 0.12s 0.12s -bash poyraz ttyp4 192.168.100.59 ertan ttyp0 192.168.100.9 8:56am 0.00s 9:52am 0.00s 0.58s 0.07s pine 0.29s 0.02s w 1: #!/usr/local/bin/perl 2: # w çıktısından saat ve o an için bağlı olan kullanıcıları alalım 3: open (WOUT, "w|"); # w komutu çıktısı WOUT tarafından alınır 4: $saat = <WOUT>; # WOUT ' un ilk satırını okur(yani aşağıdaki satır) #(11:09am up 30 days, 2:31, 3 users, load average: 0.06, 0.07, 0.01) 5: $saat =~ s/^ *//; #baştaki boşlukları çıkarır 6: $saat =~ s/ .*//; # ilk kelimeden sonraki her şeyi çıkartır(sondaki newline hariç). #Kısaca 5. ve 6. satırlar saat'i(11:09am) elde eder. $saat =~ s/pm|am$//; #Not: sondaki -am- veya -pm- gösterimini kaldırmak istersek bu satırı ekleriz. 7: <WOUT>; #WOUT dan ikinci satırı okur bu satır bizim için gereksizdir. Aşağıdaki Başlık satırını atlat(geç) işlevi gerçekleşir. #[USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT] 8: @kullanicilar = <WOUT>; #kalan satırlar @kullanicilar dizisine okunur. 9: close (WOUT); #WOUT dosyasıyla işimiz bitti.Sistem kaynaklarını tüketmemek için kapattık. 10: foreach $kullanicilar (@kullanicilar) {#@kullanicilar'ın her bir elemanı, kullanıcı bilgisinin 1 satırını içerir. 11: $kullanicilar =~ s/ .*//; # programımız, bu satırın ilk kelimesine(kullanıcı adı) ihtiyaç duyar# .Bu yüzden 10,11 ve 12: } #12 satırlarda döngü tamamlanınca newline hariç her şey temizlenir dizide sadece kullanıcı listesi bulunur. 13: print ("Saat: $saat "); 14: print ("Halen bagli olan kullanicilar:\n"); 15: $oncekikullanici = ""; 16: foreach $kullanici (sort @kullanicilar) { #kullanıcılar alfabetik sıralanıyor 17: if ($kullanici ne $oncekikullanici) ##Birden fazla aynı kullanici bağlantısı varsa, $oncekikullanici son basılan #kullanici adını tutar. Ve $kullanici içindeki değer, $oncekikullanici ile aynı ise basılmaz # ve uygun ise basılır 18: print ("\t$kullanici"); 19: $oncekikullanici = $kullanici; 20: } 21: } çalışması; ertan> ./program.pl Saat: 11:24 Halen bagli olan kullanicilar: ertan ftpadmin poyraz DOSYADAN DOSYAYA YÖNLENDİRME Unix' te standart error ve standart çıktıyı aynı dosyaya yönlendirir. sh komutu olarak şöyle yazılır. $ program >dosya1 2>&1 Aşağıdaki program standart çıktı ve standart error dosyalarının yönlendirilişiyle ilgili bir örnektir. Örnek : #!/usr/local/bin/perl open (STDOUT, ">Yazdir") || die ("STDOUT dosya acma hatasi"); open (STDERR, ">&STDOUT") || die ("STDERR dosya acma hatasi"); print STDOUT ("Satir 1\n"); print STDERR ("Satir 2\n"); close (STDOUT); close (STDERR); çalışması; programın ekrana çıktısı yoktur.Çıktı Yazdir isimli dosyayadır. Yazdir isimli çıktı dosyasının içeriği şöyledir. Satir 2 Satir 1 Sıralı yazmadığını gördük çünkü işletim sisteminin özelliğinden dolayı değerler buffer' dadır ve buradan önce STDERR ' e yazar. Bu problemi çözmek istersek dosya için buffer' ı kullanmama işlemi yapılır. Önce select ile dosya seçilir. Sonra $| sistem değişkenine 1 atanır. Eğer $| değişkenine 0 olmayan değer atanırsa buffer kullanılmaz. Tıpkı $~ ve $^ gibi $| da son kullanılan dosyaya etkilidir ki o dosya select ile son seçilendir. Eğer select kullanılmamışsa STDOUT'dur. Şimdi $| kullanarak önceki örnekten farklı olarak sırayla yazan programı görelim. Örnek : #!/usr/local/bin/perl open (STDOUT, ">Yazdir") || die ("STDOUT dosya acma hatasi"); open (STDERR, ">&STDOUT") || die ("STDERR dosya acma hatasi"); select (STDOUT); $| = 1; #buffer'ı kapat.Seçilen dosya yazdırma kanalını aç,seçilen dosya bir önceki satırda belirlendi:STDOUT. # Not: Aslında STDOUT default dosya olduğundan onu select ile seçmeye gerek yoktu sadece $| = 1; yeterliydi. print STDOUT ("Satir 1\n"); print STDERR ("Satir 2\n"); close (STDOUT); close (STDERR); Yazdir dosyası içeriği aşağıdaki gibidir. Satir 1 Satir 2 OKUMA VE YAZMA ERİŞİMİ TANIMLAMA Okuma ve yazma erişimi ile dosyayı açmak için dosya adından önce +> kodlanır. open (OKUYAZ, "+>dosya.dat"); bu erişimle dosyanın bir kısmının üzerine yazma hakkı almış olursunuz. Bu tip kullanımlarda en verimli çalışma seek ve tell fonksiyonlari ile birlikte gerçekleştirilir. Bunlar dosyada karakter(ler) atlama işlevi sağlar. İlerde inceleyeceğiz. Not : ayrıca +< eki' de okuma ve yazma amaçlı tanımda kullanılabilirler. open (OKUYAZ, "+<dosya.dat"); < eki okuma amaçlı tanımdır bu demektir ki aşağıdaki iki örnek aynıdır. open (OKU, "<dosya.dat"); open (OKU, "dosya.dat"); close Fonksiyonu : dosya kapatır. Eğer | ile komut şeklinde kullanıldıysa (open (DOSYA, "cat dosya*|"); ) gibi O takdirde komut bitene kadar program bekler. print, printf, write Fonksiyonu : Bunları görmüştük. select Fonksiyonu : Bir dosyayı default yapmak için kullanılır. Bunu da görmüştük. eof Fonksiyonu : Dosya sonunu kontrol eder. Okunacak kayıt kalmamışsa 0 olmayan değer döndürür. Eğer okunacak kayıt varsa 0 döndürür. <> işaretlerinden etkilenir. eof and eof() farklıdır. eof nin <> işaretlerden nasıl etkilendiği görülür. Aşağıdaki örnekte bu durumu gözleyebiliriz. Örnek programda komut satırından isimleri verilen dosyalar(1 veya daha çok)'ın içeriği basılır. dosya1 içeriği şöyle olsun; Bu ilk dosyanın ilk satırı Bu ilk dosyanın ikinci satırı Dosya2 içeriği ise ; Bu ikinci dosyanın ilk satırı Bu ikinci dosyanın ikinci satırı Örnek : eof ve <> birlikte kullanımı; #!/usr/local/bin/perl while ($kayit = <>) {#<>operatörü der ki; adları komut satırında verilen dosyalardan ,okunmakta olanın sıradaki satırını oku print ($kayit); if (eof) { # ve yazdır. #dosya sonu geldiyse aşağıdaki mesaji bas print ("-- Kullanımdaki dosyanın Sonu --\n"); } } çalışması; ./program.pl dosya1 dosya2 Bu ilk dosyanın ilk satırı Bu ilk dosyanın ikinci satırı -- Kullanımdaki dosyanın Sonu -- Bu ikinci dosyanın ilk satırı Bu ikinci dosyanın ikinci satırı -- Kullanımdaki dosyanın Sonu -- Not: dosya sonu kontrolünde eof ve eof() kullanılır ama ikisi birlikte kullanılmaz. Şimdi de parantezli eof kullanımına bakalım. Örnek : #!/usr/local/bin/perl while ($kayit = <>) { print ($kayit); if (eof()) { print ("-- Kullanımdaki dosyanın Sonu --\n"); } } çalışması ; ./program.pl dosya1 dosya2 Bu ilk dosyanın ilk satırı Bu ilk dosyanın ikinci satırı Bu ikinci dosyanın ilk satırı Bu ikinci dosyanın ikinci satırı -- Kullanımdaki dosyanın Sonu -- Çıktıyı incelediğinizde dosya sonu mesajının her dosyanın sonunda değil tüm dosyaların okunması Sonunda bir defa yazdığını görüyorsunuz. eof() kullanımında ancak tüm dosyalar bitince true döner. Birinci dosya sonunda kontrolde false 'e döner. Çünkü sırada okunacak ikinci dosya vardır. Yalnız şuna dikkat etmemiz gerekir eof ile eof() arasında sadece <> operatörüyle kullanımda fark vardır. Yalnız başlarına kullanımda eof ile eof() arasında fark yoktur. DOSYA İSİMLERİNİN DOLAYLI KULLANIMI $dosya = "DOSYAM"; open ($dosya, ">dosya.dat"); gibi... Örnek : #!/usr/local/bin/perl &dosya_ac("OKU", "", "dosya1"); &dosya_ac ("YAZ", ">", "dosya2"); while ($satir = &dosyadan_oku("OKU")) { &dosyaya_yaz("YAZ", $satir); } sub dosya_ac { local ($dosya_degiskeni, $dosya_modu, $dosya_adi) = @_; open ($dosya_degiskeni, $dosya_modu . $dosya_adi) || die ("$dosya_adi dosyası açılamadı... "); } sub dosyadan_oku { local ($dosya_degiskeni) = @_; <$dosya_degiskeni>; } sub dosyaya_yaz { local ($dosya_degiskeni, $satir) = @_; print $dosya_degiskeni($satir); } çalışması, program ekrana çıktı vermez. dosya1 adlı dosyayı dosya2 ye kopyalar. more dosya1 veya cat dosya1 gibi komutlarla baktığımızda her iki dosyanın da içerik olarak aynı olduğunu görürüz. $ cat dosya1 Bu ilk dosyanın ilk satırı Bu ilk dosyanın ikinci satırı $ cat dosya2 Bu ilk dosyanın ilk satırı Bu ilk dosyanın ikinci satırı DATALARI ATLAMA VE YENİDEN OKUMA == seek == == tell == Şimdiye kadar hep ilk sıradan başlatarak okuma örnekleri gördük. Perl bize iki hazır fonksiyon sunar.Bunlar seek ve tell fonksiyonlarıdır. Bu fonksiyonlar dosyada ileri, geri hareketi veya tekrar okuma gibi işlevlere sahiplerdir. seek fonksiyonu : bu fonksiyon dosya içinde ileri ve geri hareketi sağlar. Formatı ; seek (dosyadeğişkeni, atlanacak karakter sayısı, konum_sabiti); eğer konum sabiti; 0 ise; dosya başı 1 ise; bulunulan konum değeri 2 ise; dosya sonu anlamı taşırlar. Örneğin; DOSYAM adlı dosyanın başına atlamak istiyorsak seek (DOSYAM, 0, 0); kodlanır. Aşağıdaki ifade bulunulan karakter pozisyonundan 80 byte (karakter) ileri atlar. seek (DOSYAM, 80, 1); aşağıdaki ifade ise 80 karakter geri gider. seek (DOSYAM, - 80, 1); dosya sonuna atlamak için ise; seek (DOSYAM, 0, 2); seek başarılı olursa true(0 olamayan değer) aksi takdirde false(0) döndürür. seek ,tell fonksiyonu ile çok sık kullanılır. tell Fonksiyonu : Mesafe döndürür. Bu mesafe dosya başı ile bulunulan pozisyon(bir sonra okunacak satır bölgesi) arası mesafedir. Birimi byte' dır. Formatı; tell (dosya_değişkeni); o an kullanılacak olan dosyanın adını saklayan değişken örneğin DOSYAM ' ın kullanım anındaki pozisyonunu elde eden kodlama şu şekilde yazılır. $pozisyon = tell (DOSYAM); seek ve tell kullanımı örneği içeren bir program yazalım. Çalışacağımız dosyanın adı dosya1 ve içindeki kayıtlar şöyle olsun; Ertan TURKMEN ANKARA TURKIYE JOE ROSE NEWYORK USA ŞAZİYE MORAL ISTANBUL TURKIYE DANIYAR ANDICAN TASKENT OZBEKISTAN Örnek: #!/usr/local/bin/perl open (GECICI_DOSYA, "dosya1"); print "Dosya yazdırılıyor ..!\n\n"; print "DOSYANIN ILK KAYDI--"; while (1) { $satir = <GECICI_DOSYA>; last if ($satir eq ""); print ($satir); if (eof()) { print "DOSYA SONU\n"; last; } $pozisyon = tell(GECICI_DOSYA); $pozisyon++; print "--Yeni SATIR--Dosyada $pozisyon.karakterdeyiz\n"; print "5 karakter sonrası: "; seek (GECICI_DOSYA, 5, 1); } çalışması: program.pl Dosya yazdırılıyor ..! DOSYANIN ILK KAYDI--Ertan TURKMEN ANKARA TURKIYE --Yeni SATIR--Dosyada 30.karakterdeyiz 5 karakter sonrası: OSE NEWYORK USA --Yeni SATIR--Dosyada 51.karakterdeyiz 5 karakter sonrası: E MORAL ISTANBUL TURKIYE --Yeni SATIR--Dosyada 81.karakterdeyiz 5 karakter sonrası: AR ANDICAN TASKENT OZBEKISTAN DOSYA SONU Not: dosya değişkeni pipe (|)' a refere ediyorsa tell ve seek kullanılamaz. Örneğin; open (DOSYAM, "cat dosya*|"); olursa aşağıdaki satır anlamsızdır $satir = tell (DOSYAM) SİSTEM OKUMA YAZMA FONKSİYONLARI Perl' de <DOSYADEGISKENI>şeklindeki ifade dosyadan en temel okuma şeklidir. Bunun dışında dosyadan okuma için iki fonksiyon daha vardır. Bunlar; read : sysread : unix' de ki fread fonksiyonu gibidir read fonksiyonuna eş değerdedir. Perl yazmak için de fonksiyonlar sunar. Örneğin unix' de ki write' a benzeyen syswrite fonksiyonu gibi. read Fonksiyonu: okuma yapar ve isteğe bağlı karakter sayısını skalar değişkene atar. read (dosyadegiskeni, sonucdegiskeni, uzunluk, atlamadegeri); ( isteğe bağlı ) okunacak skalar veya okunacak dosya' ı temsil eder. array değişken karakter sayısı (okunan buraya depolanır) Örn: read (DOSYAM, $skalar, 80); bu çağrı ile DOSYAM' dan 80 karakter(byte) okunur ve $skalar değişkenine depolanır. Eğer DOSYAM dosyasının sonuna gelinirse 0' a döndürür, normalde okunan karakter(byte)leri döndürür. Eğer hata oluşursa read, null string döndürür. read kullanılarak skalar değişkene bir argüman eklenebilir. Bu argüman değişken içinde atlanacak byte sayısını verir. Örn: read (DOSYAM, $skalar, 40, 80); komutu ile read, DOSYAM' dan bir başka 40 byte okur ve bunu $skalar 'a kopyalarken daha önce depolanmış 80 byte'ı atlar. sysread Fonksiyonu : Mümkün olduğunca hızlı data okumak için read yerine sysread kullanabilirsiniz. Formatı; sysread (dosyadegiskeni, sonucdegiskeni, uzunluk, atlamadegeri); ( isteğe bağlı ) Örn: sysread (DOSYAM, $skalar, 80); sysread (DOSYAM, $skalar, 40, 80); read ile kullanımı aynıdır. * sysread UNIX' in read komutu ile aynıdır. syswrite Fonksiyonu : Bu fonksiyonda olabildiğince hızlı yazmak için kullanılır. UNIX' deki write komutuyla aynıdır. Formatı: (dosyadegiskeni, sonucdegiskeni, uzunluk, atlamadegeri); syswrite (dosyadegiskeni, data, uzunluk, atlamadegeri); yazılacak datanın byte atlama dosyayı temsil nerede olarak değeri eder. Örnek: olduğu uzunluk syswrite (DOSYAM, $skalar, 80); $skalar' ın 80 byte' ını DOSYAM' a yazar. syswrite (DOSYAM, $skalar, 40, 80); ( isteğe bağlı ) $skalar' da ki ilk 80 byte' ı atladıktan sonra sonraki 40 byte' ı, DOSYAM' a yazar. Not: Geniş bilgi için UNIX' in read ve write komutlarına bakınız. getc Fonksiyonu Kullanarak Karakter Okuma : dosyadan bir karakter okur. Formatı; $karakter = getc (dosya); döndürülen okunacak dosya karakter Örn: $tek = getc(dosya); dosya' dan tek karakter okur, $tek ' e kopyalar.getc, hotkeys uygulamalarında çok yararlıdır. Örnek : #!/usr/local/bin/perl &hot_keys_baslat; while (1) { $tek_al = getc(STDIN); last if ($tek_al eq "\\"); # \ karakteri giriş sonu olacak $tek_al =~ tr/a-zA-Z0-9/b-zaB-ZA1-90/; # ne yazılırsa bir sonrakini elde eder print ($tek_al); } &hot_keys_son; print ("\n"); sub hot_keys_baslat { system ("stty cbreak"); system ("stty -echo"); } sub hot_keys_son { system ("stty -cbreak"); system ("stty echo"); } Çalısması: program çalıştığında siz ne yazarsanız bir sonrakini yazar. Yani a yazarsanız b , 1 yazarsanız 2 gibi... -- Programdan çıkmak için \ tuşuna basınız .-- a1d yazarsak, ekranda b2e görünür. hot_keys_baslat alt programı, hot key girişi için çalışma çevresini düzenler. system fonksiyonu, argüman alır ve icra eder. stty -cbreak, bir anda bir karakter almasını sisteme söyler. stty echo ise yazılan karakterin ekranda görülmemesini söyler. hot_keys_son altprogramı ise normal çalışma moduna döndürür. binmode Fonksiyonu : bu fonksiyon kullanılarak binary dosya okunur. Format; binmode (dosya değişkeni); binmode (DOSYAM); normalde DOS ve benzeri çevrede çalışmadıkça buna ihtiyacınız yoktur. DİRECTORY YÖNETME FONKSİYONLARI mkdir Fonksiyonu : DIR yaratır. Formatı; mkdir (DizinAdı, İzinDurumu); isim (octal değer) Örnek: mkdir ("/u/pub/dene", 0777); mkdir ("yeni", 0644); gibi ... İzin Listesi: 0 : Hak yok 1: icra hakkı 2:yazma hakkı 3:yazma ve icra hakkı 4:okuma hakkı 5:okuma icra hakkı 6:okuma yazma hakkı 7:tüm haklar Ör: chmod 751 dene.dat Anlamı : dene.dat dosyası üzerinde ; Dosya sahibinin her hakkı -7-vardır. Aynı gruptakilerin okuma ve icra hakkı-5- var. Diğerlerinin sadece icra hakkı -1-var. 4000 userID icra 2000 grupID icra 1000 sticky bit 0400 sahibi okur 0200 sahibi yazar 0100 sahibi icra eder 0040 sahibin grubu okur 0020 sahibin grubu yazar 0010 sahibin grubu icra eder 0004 diğerleri okur 0002 diğerleri yazar 0001 diğerleri icra eder 0777 Herkesin her hakkı var(okur,yazar,icra eder) 0444 Herkes okur 0111 Herkes icra eder .. gibi chdir Fonksiyonu : DIR değiştirir. Örnek : chdir ("/u/pub/yeni"); Çalışmak için path’de verilen (yukardaki örnekte-/u/pub/yeni- Dizinine geçilir. Önceki öğrendiklerimizlerden yararlanarak şu şekilde de kullanabiliriz. $dir="/u/pub/"; chdir ($dir . "yeni") opendir Fonksiyonu : Dizindeki dosya listelerini almak için kullanılır. opendir (DIRdegiskeni,DIRadı); DIRdegiskeni : DIR’ı temsil etmesi için kullanılır. DIRadı : açılacak DIR Örnek : opendir (DIR, "/u/pub/yeni"); DIR, /u/pub/yeni ‘yi temsil eder. Closedir Fonksiyonu : Açılmış DIR (dizin) kapatır. closedir (DIR); readdir Fonksiyonu : DIR açıldıktan sonra içindeki dosyalara veya alt dizinlere erişimi sağlar. readdir (dir); Örnek : #!/usr/local/bin/perl opendir(HOMEDIR, "/home/ertan/perl") || die ("açılamadı"); while ($dosyaadi = readdir(HOMEDIR)) { print ("$dosyaadi\n"); } closedir(HOMEDIR); Çalışması; $ program.pl lo.pl gazi.pl gazi1.pl user-ekle passwd_ekleyen.txt db-script guestbook order.htm formmail.pl register.pl register.htm kidofwais.pl wais msq-db-query msq-db-query.save db-ac.html db-ara.html anim.pl db-cikti.html db-detay.pl db-ara.pl Şimdide listeyi sıralayarak veren bir program; Örnek : #!/usr/local/bin/perl opendir(HOMEDIR, "/home/ertan/perl") || die ("açılamadı"); @dosyalar = readdir(HOMEDIR); closedir(HOMEDIR); foreach $dosyaadi (sort @dosyalar) { print ("$dosyaadi\n"); } Çalışması; program.pl Çalıştırıldığında DIR, alfabetik olarak listelenir. ... ... ... sub7.pl tamkelime-ara.pl tree1 tumdeara tumdosyada-strara until1 user-ekle usprg.pl wais while1 yazilandosya yeni zaman telldir ve seekdir Fonksiyonları : Bunlarda tell ve seek gibi işlev görürler. Fark olarak dosya değil dizin içindeki dosyalar arasında ileri geri atlama imkanı sağlarlar. telldir formatı; dosyalistesindedosyanınkonumu = telldir(dir); seekdir formatı; seekdir(dir, dosyalistesindedosyanınkonumu); dir değeri, dosyalistesindedosyanınkonumu değerine set edilir. rewinddir Fonksiyonu : DIR içindeki dosya listelerinin başına döner tekrar başlatma (okumaya, listelemeye) imkanı verir. Formatı; rewinddir (dir); rmdir Fonksiyonu : Bu fonksiyon boş DIR’ı siler. Formatı; rmdir (dir); Dır silinirse 0 olmayan değer döner aksi 0’dır. DOSYA NİTELEME FONKSİYONLARI Perl ,dosyaların davranışlarını niteleme, düzenleme fonksiyonları sunar. Başlıcaları; · · · İsimdeğiştirme-silme fonksiyonları · · · Link, sembolik link kurma fonksiyonları · · · Dosya izinlerini düzenleme fonksiyonları · · · Diğer nitelik fonksiyonları Relocation (taşıma, isimdeğiştirme, silme) Fonksiyonları : İki adet fonksiyonu vardır. rename : taşır veya isim değiştirir. unlink : siler Rename Fonksiyonu : rename (eskiad, yeniad); rename ("eski", "yeni"); rename ($eski, ¥iad_al); rename ("/u/pub/eski", "/u/pub/yeni"); taşıma işleminde rename(“eski”, “yeni”); böyle durumlarda –e (mevcut mu?) ile test edip işlemi yapabiliriz. ... -e “yeni” || rename (eski, yeni); gibi... unlink Fonksiyonu : Formatı : degisken = unlink (dosyalistesi); Silinendosyalar 1 veya fazla dosya Örnek : @silineceklistesi = ("dosya1", "dosya2"); unlink (@silineceklistesi); delete yerine unlink ismini almasının sebebi şudur. Aslında o dosya’a yapılan referans veya link yok edilir. Linklerle ilgili bilgileri inceliyelim. Link ve Symbolic Link Fonksiyonları : Aslında UNIX’de dosyalar birden fazla DIR içerebilirler. Aynı zamanda her bir DIR, dosyaya bir referans veya link içerir. Aşağıda link yaratılması ve erişimi izah ediyor. Not : Bir dosyaya birden çok link refere edilmişse, unlink birisini siler. (ve tabii dosya hala referanslıdır.) Link Fonksiyonu : Mevcut dosyaya link yaratır. (hard link) link (yenilink, dosya) Yaratılan link edilen dosya Link Link başarılı ise true döndürür. Örnek : link (“/u/pub/dosya”, “/u/ertan/yenidosya”); Link yaratıldıktan sonra ilerde unlink aşağıdaki gibi kullanılmışsa unlink (“/u/pub/dosya”); “/u/ertan/yenidosya” ‘ya referans hala mevcuttur. Symlink Fonksiyonu : Sembolik link oluşturur. symlink(yenilink, linkdosyası); Yeni yaratılan link link edilen dosya symlink("/u/pub/dosya", "/u/ertan/yenidosya"); komutla, /u/ertan/yenidosya, /u/pub/dosya’ ya sembolik linklenmiştir. Şimdi unlink (“/u/pub/dosya”) komutu ile dosya silinirse artık /u/ertan/yenidosya 'a link kalmamıştır. Eğer /u/pub/dosya yeniden yaratılırsa eski sembolik link (/u/ertan/yenidosya) yeniden oluşur. Readlink fonksiyonu : Link olan dosyanın adını okur. Format; dosya = readlink (linkadı); Dosya Adı sembolik link Yani eğer “/u/ertan/yenidosya” bir başka dosyaya sembolik linkli ise readlink link edilmiş dosyanın adını döndürür.Readlink eğer sembolik link yoksa boş string döndürür. $linkname = readlink("/u/ertan/yenidosya"); içeriği /u/ertan/yenidosya dır. Örnek : sembolik linkli dosyaları bastıran bir program #!/usr/local/bin/perl $dir = "/home/ertan/perl"; opendir(MYDIR, $dir); while ($ad = readdir(MYDIR)) { if (-l $dir . "/" . $ad) { print ("$ad soft link: "); print (readlink($dir . "/". $ad) . "\n"); } } closedir(MYDIR); Çalışması; (Not:Önce mkdir dene ve ln -s dene dene1 komutlarını girelim ve dene isimli DIR(dizin)açarak bunu dene1 dosyasina soft(symbolic) linklemiş olalım.Sonra da aşağıdaki komutla programı çalıştıralım.) $ program.pl dene1 soft link: dene $ İzin Hakları : chmod : Erişim izni hakkı. chown : Sahibini belirleme ,değiştirme. umask : Default erişim izin hakkı Chmod (izin, dosyalistesi) ; Örnek : @dosyalist = ("dosya1", "dosya2"); chmod (0777, @dosyalistesi); dizide isimleri bulunan dosyalara rwx(7) hakları verilir. chown Fonksiyonu : chown (user-kimlik, group-kimlik, dosyalistesi); numeric numeric user ID grup ID dosya (lar) (mevcut grup ID korunacaksa -1) Örnek : @dosyalist = ("dosya1", "dosya2"); chown (17, -1, @dosyalist); Unix’te user-ID ve grup ID /etc/passwd dosyasından alınabilir. Perl’de getpwnam sistem fonksiyonu (Sistem fonksiyonları konusunda incelenecek) bu işi görür. umask Fonksiyonu : Bir dosya/DIR yaratırken onun default bir erişim izin hakkı olsun. İstersek bu işlemi umask ile gerçekleştiririz. Syntax : umask değeri=umask(yeni umask değeri) Örneğin bundan sonra yaratılacak dosyalardan grup erişimi ve herkese erişimi kaldırmak istiyorsak $izin=umask(0022); yeni değeri tutar Eğer umask’ı , umask() şeklinde kullanırsak şu anki değeri atar. İZİNLERLE İLGİLİ DOSYA TEST OPERATÖRLERİ Operatör Açıklama -g Dosya grup ID bit setine sahip mi ? -k Dosya sticky bit setine sahip mi ? -r Dosya okunabilir dosya mı? -u Dosya user ID bit setine sahip mi ? -w Dosya yazılabilir dosya mı? -x Dosya icra edilir dosya mı? -R Sadece gerçek user mı okuyabilir? -W Sadece gerçek user mı yazabilir ? -X Sadece gerçek user mı icra edebilir? DİĞER NİTELİK ÖZELLİKLERİ : truncate Fonksiyonu : dosya uzunluğunu kısaltır. truncate (dosya, uzunluk); sabit ve değişken dosya’ın yeni uzunluğu (byte) olabilir eğer dosya uzunluğu truncate (DOSYAM, 5000) gibi bu rakamdan kısa ise bir şey yapmaz stat Fonksiyonu : Dosya ile ilgili bilgi verir. Örnek : stat (dosya); Dosya adı veya Dosya adı içeren değişken stat bir liste döndürür Dosya’ın bulunduğu aygıt Bu dosya için dahili referans numarası (inode no) Dosya erişim durumu Dosya yapılan hard link sayısı Dosya sahibinin numeric user ID’si Dosya sahibinin numeric grup ID’si Eğer dosya device ise, device tipi Byte olarak dosya ölçüsü Dosya’a son erişim Dosya’a son düzenleme Statüsünde son değişiklik Dosya input/output işlemlerinde kullanılacak en büyük blok ölçüsü Dosya’a ayrılan blok sayısı Stat ile Döndürülen Bilgiyi Kontrol Eden Dosya Test Operatörleri : Operatör Açıklama -b Blok device mı? (mount edilebilir disk mi?) -c Character device mı? (bir I/O device mı?) -s Boş olmayan dosya mı? -t Bir terminalimi temsil ediyor? -A Ne kadar önce erişildi? -C İnode erişimi ne kadar zamanda yapıldı? -M Düzenleme ne zaman yapıldı? -S Dosya socket mi? Not: Ek bilgi için unix’in stat komutuna bakınız. require fonksiyonu: Bir dosyayı, programınıza eklemek için kullanılır. Diyelim ki dosyam.pl isimli dosya var. Bunu programımızın bir parçası olarak almak istiyoruz. require ("dosyam.pl"); komutu bu işlevi yerine getirir. Perl, require'ı görünce o dosyayı default dizini tutan @INC' de arar. Bulunursa file içindeki ifadeler icra edilir. Bulunamazsa program hata mesajı vererek kesilir. (dosyam.pl, @INC dizininde bulunamadı gibi..) bir altyordam çağrısı içinde iken çağrılan dosyanın (örneğin dosyam.pl) son ifadesi dönüş değeri olur örneğin, dosyam.pl in son satırı: $degisken = 14; ise bu değer(14) dönüş değeri olur.(0'dan farklı değer). $degisken = 0; ise dönüş değeri 0 olur. Bu durumda; dosyam.pl did not return true value mesajı çıkar. NOT: Bu durumlarda çağrılan dosya uzantıları normalde .pl dir. Herhangi bir scalar değeri require' e geçirebilirsiniz. Aşağıdaki kodlama geçerlidir. @reqlistesi = ("dosya1.pl","dosya2.pl", "dosya3.pl"); require ($reqlistesi[$0]); require ($reqlistesi[$1]); require ($reqlistesi[$2]); Eğer require; şeklinde dosya isimsiz olarak kodlanırsa, $_ değişkeninin değeri olan dosya alınır ve icra edilir. NOT: Bir dosya sadece bir kez require ile alınabilir. Bu dosyanın herhangi bir kod bloğu bir çok kere Gerekirse system veya eval kullanılmalıdır. REQUIRE FONKSİYONU VE ALTYORDAM KÜTÜPHANESİ require , altyordam kütüphanesi yaratma imkanı da verir ve onları tüm perl programlarında kullanabilirsiniz. Altyordam kütüphanesi yaratma adımları: 1- Kütüphane ' nin hangi <DIR> da oluşturulacağını kararlaştır. 2- Altyordamları değişik file' lara ayır ve bu <DIR>'a kaydet. 3- Her bir file' a 0 olmayan değer döndürmesi(true) için icra edilebilir bir ifade ekle. Ayrıca bir boş programda 0 döndürür. Bunun en kolay yolu programın en sonuna 1; eklemektir. 4- programı çalıştırdığınızda -I seçeneğini kullanarak altyordam dizininin (<DIR>) adını tanımlayınız. [Alternatif olarak require' ı çağırmadan önce @INC dizisine, altyordam<DIR> ını da ekleyebilirsiniz. ) Örneğin; /u/ertan/perl/sub/dosya.pl için (Dosya altyordamını içeren dosya; dosya.pl <DIR>(dizin) de yukarıdaki dizin (/u/ertan/perl/sub) ) bu durumda, unshift (@INC, "/u/ertan/perl/sub"); require ("dosya.pl"); kodunu kullanırız. unshift çağrısı, /u/ertan/perl/sub dizinini @INC dizisine ekler. Daha sonra o an çalışan programın parçası olarak, require buradan okur.] NOT: @INC ' e eklemek için unshift kullanın push değil. Çünkü push en sona ekler ve bu durumda DIR' ın taranması gerekir. ÖZEL DAHİLİ DEĞERLER Üç tanedir. __ LINE __ -àprogramın son satırı __ FILE __ -àprogramın son dosyası __ END __ -àdosyanın sonu die ve warn ile kullanılan değerlerdir. __ LINE __ ve __ FILE __ hata anında satır no ve file adını kullanırlar. __ END __ ise dosya sonu anlamında olup bundan sonraki satırlarda datalar bulunur .DATA değişkeni ile birlikte kullanılır.(__ END __ sonrası data olarak değerlendirilir). Daha önce de gördüğümüz şu örneği hatırlayalım. Örnek #!/usr/local/bin/perl $kayıt = <DATA>; print ("$kayıt"); __END__ Bu benim kayıtım. Çalışması; $ program.pl Bu benim kayıtım. $ Programda _END_ program sonunu belirler. 2.satır DATA özel dosyasını okur.Okunan kayıt ise _END_ den sonraki ilk satırdır ve bu satır $kayıt değişkenine alınır. DBM Dosyaları Kullanımı : (database management: veri tabanı yönetimi) Perl DBM dosyalarına erişimi sağlayan dbmopen ve dbmclose fonksiyonlarına sahiptir. Bunlar tie ve untie fonksiyonları ile aynı işi görür. Fark perl5 version farkıdır. dbmopen Fonksiyonu : Formatı : dbmopen (dizi, dbmdosyası, permissions); Kullanılacak açılacak Birleşik dizi erişim izin hakkı DBM dosyası DBM dosya açıldığında, bu dosyanın key leri, bileşik dizinin index’li olurlar (onları temsil ederler). , Değerlerine ise bu yöntemle erişilir. dbmopen, mevcut bileşik dizi varken açılırsa dizi içerikleri silinir. dbmclose Fonksiyonu : dbmopen ile açılan DBM dosyalarını kapatır. dbmclose (dizi); database dosyası ile ilişkili olan birleşik dizi REFERANSLAR Referans herhangi bir diziye, değişkene, altprograma işaret koymaktır denilebilir. Bir referans, bir değer için adrestir. Referanslar karışık data yapıları oluşturmada çok faydalıdırlar. Karışık data yapılarını gerçekte referanssız tanımlayamazsınız. Perl5 hard ve sembolik referanslar sunar. Bir sembolik referans; değişken adını içerir. Sembolik referanslar değişken adı yaratmak ve onları çalışma anında adreslemek için çok yararlıdırlar. Temel olarak sembolik bir referans bir file adına benzer veya UNIX’ deki soft link gibidir. Hard referans ise hard linkler gibidirler. Sadece aynı yere bir başka yoldur. Hard referanslar referans sayısını izler bu sayı 0 olunca başvurulan yeri serbest bırakır. Referansları Kullanma : Bir skalar değer bir değişkene başvursun. $gosterge. Herhangi bir skalar bir hard referans tutabilir. Çünkü diziler hash’lar(bileşik diziler) skalar içerirler . Bunları dikkate alarak kompleks yapılar inşa edilebilir. $gosterge’nin değerini, bir diziye gösterge olarak kullanmak için dizi içindeki maddeye başvurulur. Şu notasyonla : @$gosterge. Bu kullanım kabaca, $gosterge nin adresini alır ve onu bir dizi olarak kullanır şeklinde anlaşılabilir. Benzer şekilde hash’lar (Bileşik Dizi) için %$gosterge gösterimini kullanırız. Bu durum hash’ın ilk elemanına işaret koyarız anlamındadır. Backslash (\) Operatörü Kullanımı : Bir operatörün adresini geçirmek için kullanılır. Genelde değişkene ikinci bir yeni referans yaratma amacıyla kullanılır. $degisken = 10; $gosterge = \$degisken; Burada; $gosterge, $degisken in değerini (10) içeren yere işaret koyar(referans verir). $degisken içindeki değeri $gostergeden alabilirsiniz hatta $degisken yok olsa dahi. Burada çalışan hard referanstır. $gosterge değişkeni , $degisken'in adresini içerir onun değerini değil.Değere erişmek için iki adet $ ile refere($$gosterge ) edilir. Örnek : #!/usr/bin/perl $deger = "ertan"; $gosterge = \$deger; printf "'\$deger' degiskeninin içindeki değer $deger olup, gösterge adresi: $gosterge\n"; printf "$gosterge memory adresindeki değer: $$gosterge\n"; Çalışması ; program.pl '$deger' degiskeninin içindeki değer ertan olup, gösterge adresi: SCALAR(0x80c1288) SCALAR(0x80c1288) memory adresindeki değer: ertan Referans ve Diziler : Perl konusunda belki en önemli nokta tüm @dizi ve %hash lar tek boyutludur ve skalar değer tutarlar ve direkt olarak dizi ve karmaşık data yapıları içermezler. Bir dizi elemanı sayı veya referans dır. Backslash operatörü ( \ ) ile skalar değişken gibi kullanılırlar. Örnek : #!/usr/bin/perl $gosterge = \@ARGV; printf "\n ARGV nin gösterge(pointer) Adresi = $gosterge \n"; $i = scalar(@$gosterge); printf "\n Argüman sayısı : $i \n"; $i = 0; foreach (@$gosterge) { printf "$i : $$gosterge[$i++];\n"; } Çalışması ; program.pl 1 2 3 4 ARGV nin gösterge(pointer) Adresi = ARRAY(0x806c378) Argüman sayısı: 4 0 : 1; 1 : 2; 2 : 3; 3 : 4; Çalışması ; program.pl Argüman sayısı: 0 Programda, komut satırından girilen değerleri saklayan @ARGV dizisi elemanları içeriği basılır. 2. satırda $gosterge referans olarak @ARGV’ye işaretlenmiştir(point). 3. satır ARGV’nin adresini basar. Siz genelde bu adresi kullanmazsınız ama başka bir diziyi kullanabilirsiniz. O dizinin ilk elemanına erişim için bu adrese ulaşmak kısa yoldur. $gosterge pointer’i dizinin ilk elemanının adresini döndürür. 74 satır scalar () fonksiyonu çağırır ve (skalar değişken tipi ile karıştırmayınız) Dizideki eleman sayısına erişir. @ARGV’ye parametreler geçirilmiştir ama scalar() tarafından istenen $gosterge pointerinin tipini tanımlamak gerekir. Bu sebepten @$pointer kullanarak bir dizi olarak parametre tipi tanımlanır. Bu durumda $gosterge tipi dizi için bir pointerdir. @$pointer in ilk elemanıın adresi bu durumda $pointer ile elde edilmiş olur. Onun eleman sayıları scalar () ile döndürülür. Bileşik dizilerde (hash) de \ operatörü kullanılabilir.Aşağıdaki örnekte Bileşik dizilerde kullanımı görelim. Örnek : #!/usr/bin/perl # bileşik dizi referansları kullanımı %Aylar = ( '01', 'Ocak', # '01' => 'Ocak', şeklinde de yazılabilirdi '02', 'Subat', '03', 'Mart', 'Agustos', '04', 'Nisan', '09', 'Eylul', '10', 'Ekim', '05', 'Mayis', '11', 'Kasim', '06', 'Haziran', '07', 'Temmuz', '08', '12', 'Aralik', ); $gosterge = \%Aylar; printf "\n Aylar Bileşik dizisinin adresi = $gosterge\n "; foreach $i (sort keys %$gosterge) { # yukarda $gosterge pointerinin bileşik dizi belirtiliyor ve key' ler ("01","02",...."12") # sort() ile sıralanıyor printf "$i. Ay = $$gosterge {$i} \n"; # ve bastırılıyor } Çalışması ; program.pl Aylar Bileşik dizisinin adresi = HASH(0x80c1294) 01. Ay = Ocak 02. Ay = Subat 03. Ay = Mart 04. Ay = Nisan #gostergesi olduğu 05. Ay = Mayis 06. Ay = Haziran 07. Ay = Temmuz 08. Ay = Agustos 09. Ay = Eylul 10. Ay = Ekim 11. Ay = Kasim 12. Ay = Aralik ÇOK BOYUTLU DİZİLERDE REFERANS : Kare, köşeli parantez kullanılır. Genel formatı; $diziReferans->[$indeks] ........tek boyutlu dizi $diziReferans->[$indeks1][$indeks2] ........iki boyutlu dizi $diziReferans->[$indeks1][$indeks2][$indeks3] ........üç boyutlu dizi şeklindedir. Örnek : #!/usr/bin/perl 0 1 2,0 2,1 2,2 3,0 3,1 $tablo = ['Siyah', 'Beyaz', ['Kartal','2000','YILI'] , ['ŞAMPİYONU', 'Puan', '100']]; print "\$tablo ->[0] = $tablo->[0] \n"; 3,2 print "\$tablo ->[1] = $tablo->[1] \n"; print "\$tablo ->[2][0] = $tablo->[2][0] \n"; print "\$tablo ->[2][1] = $tablo->[2][1] \n"; print "\$tablo ->[2][2] = $tablo->[2][2] \n"; print "\$tablo ->[3][0] = $tablo->[3][0] \n"; print "\$tablo ->[3][1] = $tablo->[3][1] \n"; print "\$tablo ->[3][2] = $tablo->[3][2] \n"; print "\n"; Çalışması ; program.pl $tablo ->[0] = Siyah $tablo ->[1] = Beyaz $tablo ->[2][0] = Kartal $tablo ->[2][1] = 2000 $tablo ->[2][2] = YILI $tablo ->[3][0] = ŞAMPİYONU $tablo ->[3][1] = Puan $tablo ->[3][2] = 100 ALT YORDAMLARA REFERANS : Bir skalar veya dizinin bir maddesine referansla aynı tarzdadır. Aşağıdaki tipte ifade edilir. $alt_prog_gosterge = sub {alt yordam bildirimleri} ; Not: referans tarafından alt yordam çağırmak için aşağıdaki tipte referans kullanmalısınız. &$alt_prog_gosterge( parametreler); Örnek : #!/usr/bin/perl sub arguman_yaz{ my ($d,$d,$f) = @_; print "$d $e $f \n"; return $d;}; $a = 1; $b = 2; $c = 4; $ilk = arguman_yaz($a,$b,$c); printf "\t$ilk\n"; $ikinci = arguman_yaz(4,5,6); printf "\t$ikinci\n"; Çalışması ; program.pl 2 4 2 5 6 5 Çok Boyutlu Dizilerle, Çalışmak İçin, Altyordam Kullanımı : Örnek : #!/usr/bin/perl @isimler = (Ahmet,Bertan,Ertan); @telefonlar = (2126840,2126841,2126842); $say = 0; &aktar_yazdir(\@isimler, \@telefonlar); sub aktar_yazdir{ my ($ad,$tel) = @_; foreach (@$ad) { print "ad[$say] = " . @$ad[$say] . " " . "\ttel[$say] = ". @$tel[$say] ."\n"; $say++; } } Çalışması: program.pl ad[0] = Ahmet tel[0] = 2126840 ad[1] = Bertan tel[1] = 2126841 ad[2] = Ertan tel[2] = 2126842 Değişkenlerde alias kullanımı Aşağıdaki tanımı inceleyelim. sub altprogram1 { local (*altdizi) = @_; $dizi_uzunlugu = @altdizi; } altprogram1 içindeki *altdizi tanımı perl' e der ki: Gerçek liste üzerinde işlem yapmak yerine kopya yap. Bu altyordam, &altprogram1(*altdizi2); gibi bir ifadeyle çağırılınca perl, altdizi ile altdizi2'nin aynı dizi değişkene başvurmasını gerçekleştirir. Bir isim alias olarak verildiğinde, o ismi taşıyan tüm değişkenler alias kullanarak başvurmuş olurlar. Bu demektir ki,bu örnekte @altdizi ve @altdizi2 aynı diziye başvururlar. altprogram1(*altdizi); Şu iki ifade, local (*altdizi2) = @_; şu ifadeye eşittir; local (*altdizi2) = *altdizi; her bir durumda, altdizi isminin alias' ı olarak altdizi2 tanımlanmıştır. Çünkü altprogram içindeki local tanımı *altdizi2 içerir ve altdizi2 ve altdizi sadece altprogram çalıştığında eşittir. Bir isim için şöyle bir alias tanımlarsak; *altdizi2 = *altdizi; ve bu ifade ana programın bir bölümünde ise, altdizi2, altprogramlar dahil tüm programda altdizi için bir alias olur. $altdizi2, @altdizi2 ve %altdizi2 (eğer tanımlıysa) değerleri kaybolur. Örnek programa bakalım: #!/usr/local/bin/perl *name2 = *name1; $name1 = 14; print ("$name2\n"); çalıştır 14 Not: alias kullanımı karışık olduğundan kesin emin olmadıkça kullanılmamalıdır onun yerine değişken adını bir stringe koyup eval ile çalıştırmak tercih edilebilir. Örneğin; $isim2 = '$isim1'; eval ("$isim2 = 14;"); # $isim1 içeriği 14 ' dür. -ÇEŞİTLİ FONKSİYONLAR Proses (İşlem-program ve komut işlem süreci) : Perl çalışan ve diğer programların yönetimi için geniş bir fonksiyon yelpazesi sunar. Bunlar 4 grupta incelenebilir. 1 - İlave proses başlatma 2 - Çalışan program veya bir başka prosesi durdurma 3 - Program veya proses icra kontrolü 4 - Program veya proses yönetme (önceki kategorilere girmeyen) Proses Başlatma : Proses yaratma ile ilgili prosesler eval, system, fork, pipe, exec, syscall’dır. Eval : Bir karakter stringi, icra edilebilir perl programı gibi davranır. Formatı; eval (string) Örnek : $yaz = "print (\"Selam size !!!\ \n\");"; eval ($yaz); Çıktısı, Selam size !!! olmalı) Eval’in kullandığı string bir karakter string sabit veya bir ifade(değeri karakter string olabilir. Örnekte string önce $yaz sonra eval 'e geçirildi. Eval’e geçirilen string print ("Selam size !!!\n"); stringidir. Eval fonksiyonu $@ sistem değişkenini kullanır. Bu değişken, icra edilebilir karakter stringini içereni belirler. $@ içeriği null stringidir ve hata anında ,hata mesajı , @$ içinde oluşur. $@ içeriğinde bir şey yoksa icra tamamdır. Örnek : eval örneği #!/usr/local/bin/perl $deger = 1; eval ("print (\"Merhaba!\\n\"); \$deger = 7;"); print ("\$deger değeri: $deger\n"); Çalışması: program.pl Merhaba! $deger değeri: 7 eval önce print(“Merhaba!\n”); sonra $deger = 7; icra eder. Örnek : eval fonksiyonu kullanarak tell fonksiyonu var mı, yok mu test eden program #!/usr/local/bin/perl open (DOSYAM, "dosya1") || die ("dosya1 açılamadı"); eval ("\$basla = tell(DOSYAM);"); if ($@ eq "") { print ("tell fonksiyonu tanımlı.\n"); } else { print ("tell fonksiyonu tanımlı degil!\n"); } Çalışması: program.pl tell fonksiyonu tanımlı. Eval çok faydalı bir fonksiyondur. Küçük programlarda çok iyi kullanıma sahiptir. Büyük programlarda ise onu dosyaya yazdırıp system ile icra etmek daha iyidir. system Fonksiyonu : Daha öncede görmüştük. system(Liste); fonksiyona geçirilen Liste’de ilk argüman icra edilecek program sonrakiler ise programa geçirilecek argümanlardır. Örnek : #!/usr/local/bin/perl @liste = ("echo", "Perl Öğreniyorum!"); system(@liste); Çalışması : program.pl Perl Öğreniyorum! System fonksiyonu ile program çalışırken çıktıda bazen karışıklık olabileceğini düşünerek bu problemin çözümü için $| sistem değişkeni set edilir. Her bir file için 1 tanımlanmalıdır.Bu tanım o dosya için buffer yok demektir. Böylece çıktılar sırayla olur. select (STDOUT); $| = 1; select (STDERR); $| = 1; gibi.. fork Fonksiyonu : Bu fonksiyon, programınızın iki kopyasını yaratır. Parent ve child proses bu kopyalar eş zamanlı çalışırlar. Syntax: $prosesid_değişkeni = fork(); Fork, child prosese 0, parent prosese 0 olmayan değer döndürür. Bu 0 olmayan değer child prosesin proses ID’sidir. Bu değer sizin hangi prosesin child, hangi prosesin parent olduğunu ayırmanıza yarar. Örnek : $deger = fork(); if ($deger == 0) { # Burası child process exit; # child proces sonu } else { # parent proses } Eğer fork çalışmazsa, dönüş değeri tanımlanmayan bir değerdir. Bu değer ilerde göreceğimiz defined fonksiyonuyla test edilebilir. fork fonksiyonu kullanırken dikkatli olunmalıdır. Mesela, her iki kopya da print ediliyorsa karışıklık olabilir, yine döngü kullanılıyorsa çok fazla kopya etkisi olur gibi... pipe Fonksiyonu : fork fonksiyonu ile birlikte tasarlanmıştır. Bu fonksiyon child ve parent proses iletişimini sağlar. formatı : pipe (giriş_dosyası, çıkış_dosyası); kullanımda olmayan dosya değişkenleri Örnek : #!/usr/local/bin/perl pipe (GIRIS, CIKIS); # GIRIS ten okutabileceğini CIKIS' a gönderir $prosesler = fork(); # program child ve parent prosese ayrılır if ($prosesler != 0) { # hangi prosesin child hangisinin parent olduğu test edilir # bu aşamaya gelindiğinde parent prosestir. Parent proses datayı CIKIS yoluyla göndereceğinden, close (GIRIS); # GIRIS erişimine gerek yoktur. Bu yüzden GIRIS’i kapatır. print ("Bir satır giriniz:\n"); $oku = <STDIN>; #Data standart girişten alınır ve print CIKIS ($oku); # CIKIS değişkeni yoluyla child prosese gönderilir } else { # bu aşamada proses child prosestir ve bu yüzden data GIRIS yoluyla alınacağından close (CIKIS); # CIKIS 'a gerek yoktur CIKIS kapatılır $oku = <GIRIS>; # GIRIS’den datayı okur.Çünki,data CIKIS’dan GIRIS 'e pipe edilmiştir print ($oku); exit (0); #child proses exit ile ölür ve GIRIS otomatikman kaldırılır } Çalışması : program.pl Bir satır giriniz : Bu bir satırdır Bu bir satırdır $ exec Fonksiyonu : Sistem fonksiyonuna benzer. Tek farkı yeni programa başlamadan önce o an çalışan programı keser. Formatı : exec (liste); İlk eleman icra edilecek program sonrakiler ise argümanlardır. exec ("mail ertan"); exec ("vi", "dosyam.dat"); program adı da kullanabilirsiniz. exec sık sık fork ile kullanılır. fork iki prosese ayırdığında child, diğer programı exec kullanarak başlatır. Daha önce system de bahsedilen buffer işlemleri , exec içinde geçerlidir. syscall Fonksiyonu : Bir sistem fonksiyonu çağırır. syscall (liste); Ilk argüman araya sokulacak sistem çağrısı, diğerleri bu çağrıya aktarılacak argümanlardır. (UNIX syscall manual sayfalarını inceleyiniz). syscall kullanımında perl’in syscall.ph başlık dosyası dahil edilmelidir. [Ör: require ("syscall.ph")] PROGRAM veya PROSES BİTİRME die, warn, exit, kill die ve warn Fonksiyonları : Programlardaki önemli mesajları, gönderme fonksiyonlarıdır. die fonksiyonu programı sonlandırır ve bir hata mesajı verir (standart error dosyasına ) die (mesaj); warn’da die gibidir. Yalnız programı sonlandırmaz, icra devam eder. Örnek : warn("UYARI!\n"); UYARI! (standart error dosyasına yazar) exit Fonksiyonu : Programı sonlandırır. exit (dönüş kodu) Geçirilecek dönüş kodu exit(2); #2 kodu ile programı bitirir. kill Fonksiyonu : kill (sinyal, proseslistesi); nümerik sinyal proses ID Listesi (fork ile döndürülen child proses ID gibi) detaylar için UNIX’de kill komutuna bakınız. sleep Fonksiyonu : Bu fonksiyon verilen saniye sayısı kadar programı bekletir. sleep (time); sn cinsinden sayı sleep(5); (5 sn bekletir) wait ve waitpid Fonksiyonları : wait fonksiyonu icrayı devreder ve child prosesin sonlanmasını belirler(fork ile yaratılan proses gibi). Bu fonksiyon argümansızdır. proses_id = wait(); Burada child proses sonlanınca wait, proses ID’yi proses_id ‘ye atar. (Sonlanan prosesin ID’si. Eğer proses yoksa dönüş değeri –1 olur.) waitpit ise üzerinde çalışmak istenilen child proses için bekler. waitpid (proses_id, waitflag); proses ID özel bekleme flag’ı default’u 0’dır(normal bekleme). beklenecek proses Eğer 1 dönerse proses bulundu, -1 dönerse bulunmadı demektir. Örnek : #!/usr/local/bin/perl $prosesid = fork(); if ($prosesid == 0) { # burası child proses kısmı print ("Basılan ilk satır\n"); exit(0); } else { # burası parent proses kısmı, $prosesid içine child prosesin ID’sini döndürür. waitpid ($prosesid, 0); print ("Basılan sonraki satır\n"); } Çalışması : program.pl Basılan ilk satır Basılan sonraki satır Not : $$ sistem değişkeni, çalışan programın proses ID’sini tutar. chroot Fonksiyonu : Bu fonksiyon root dizini tanımlar. chroot (dir); yeni root DIR chroot ("/u/public"); CGI (Common Gateway Interface) CGI, web sayfalarının daha etkin ve etkileşimli kullanımına yönelik olarak tasarlanmış bir standarttır. Perl programları cgi olarak da çalışabilirler. Bu sayede browser(netscape,explorer gibi) sayfasıyla web server arasındaki data iletişimi gerektiğinde karşılıklı olmak üzere gerçekleşir. Perl cgi programlarına erişmek ve çalıştırmak için web browser sayfasından formlar veya link yoluyla (a href="www.gazi.edu.tr/cgi-bin/ornek1.pl...) veya URL adres satırından tam path(dosya yolu) (www.gazi.edu.tr/cgi-bin/ornek1.pl) verilerek perl programınızı çalıştırabilirsiniz. Daha sonra işleyeceğimiz Web sayfası formları haricinde cgi kullanımını bir örnekle görelim isterseniz. Programımız browser'ımızın sayfasına ; Merhaba ben ilk cgi programınızın çıktısıyım !): yazsın. Zemin rengi beyaz yazı büyük (h1) ve rengi de mavi olsun. Ayrıca bir önceki sayfaya dönmeyi sağlayan Geri butonu bulunsun. Program adına da ornek1.pl diyelim. Program yazıldıktan sonra bir web browser -sorgulayıcıprogramdan (Netscape, i.explorer, v.b) çalıştırabilmek için web server'ın bulunduğu sistemin cgi-bin dizinine konulmalı ve icra hakkı verilmelidir(chmod 755 ornek1.pl). Şimdi programımızı kodlayalım. #!/usr/local/bin/perl print "Content-type:text/html\n\n"; print "<html><head>\n"; print "<title>Örnek1</title>\n"; print "</head>\n"; print "<body bgcolor=\"white\" text=\"blue\">\n"; print "<center><h1>Merhaba ben ilk cgi programınızın çıktısıyım !)):</h1>\n"; print "<FORM>\n"; print "<FONT color=#ff9900 size=1>\n"; print "<INPUT onclick=history.go(-1) type=button value=\"Geri\">\n"; print "</FONT></FORM>\n"; print "</body></html>\n"; Programımızın satırlarını incelediğinizde 2. satır çok önemli bir özelliğe sahiptir. Bu satır da print "Content-type:text/html\n\n"; kodunu görmektesiniz. Cgi programlarda bu satır programın çıktısının web(html) sayfasına olacağını bildirmektedir. Bu satırın kodlanmasında dikkat edilecek bir nokta da genel kabul gören bir uygulama olarak bir üst satırının boş olmasıdır. Programımızı yazdık ve cgi-bin dizinine koyduk(icra hakkı da verdik tabii). O halde şimdi çalıştırabiliriz. Burayı kliklermisiniz? Web browser'ınızın sayfasında Merhaba ben ilk cgi programınızın çıktısıyım !): yazdığını gördünüz değil mi?. O halde ilk cgi programımızı çalıştırmış olduk. Devam edelim...Şu ana kadar sadece sistemdeki programı çalıştırdık ve çıktısını aldık. Pekala etkileşimli olarak data kullanımını nasıl gerçekleştiririz? Genelde bu işlev için web sayfasında formlar kullanılır. Formlar yoluyla data girer onu sisteme yollar dosyaya kaydeder veya işleyip çıktısını alırız ya da bir sorgulama datası gönderip sistemden onu değerlendirip bize uygun çıktıları göndermesini sağlayabiliriz. Formlar Form tanımı için ilk ifade <form> dur formun sonunu ise </form> gösterimi belirler. Bu iki gösterim arasında ise kullanacağımız form'a ait özellikler kodlanır. Formlarda formun adını tutan bir NAME alanı,çalıştırılacak .cgi (.pl) programının tam URL 'nı tutan bir ACTION alanı ve data iletişim metodunu (get , post) tutan bir METOD alanı tanımlanmalıdır. Formlarda amaca göre değişen daha bir çok tanım şekli sözkonusudur. Örneğin, CHECKED : radyo butonu veya checkbox larda seçilmiş olma durumu, MAXLENGTH : form elemanına girilecek en fazla karakter sayısı, SIZE bar oluşur : giriş yapılan alanın ölçüsü,(eğer MAXLENGTH, SIZE dan genişse scroll bu sayede normalde gözükmeyen alan gözükür). TYPE text). : giriş alanının tipi(checkbox, hidden, password, radio, reset, submit, ve VALUE : Alan için varsayılan değer. mesela bir form da bir text alanı tanımlayalım. KODU: <form> <INPUT TYPE=text NAME=Soyadı VALUE=Turkmen SIZE=25 MAXLENGTH=50> </form> Web sayfasında görünümü: Bu kod ile bir giriş alanı tanımlanır. Bu alanın html sayfasında default değeri Turkmen olarak gözükür ve alan genişliği 25 karakterdir(Web sayfasındaki görüntü olarak).Biz bu alana,yapılan tanım gereği 50 karaktere kadar değer girebiliriz. Bazı form kullanım örnekleri: KODU: <form> <INPUT TYPE=checkbox NAME=beyaz CHECKED>Beyaz severmisiniz? <INPUT TYPE=checkbox NAME=mavi>Mavi severmisiniz? <INPUT TYPE=submit VALUE="Renk"> </form> Web sayfasında görünümü: Beyaz severmisiniz? Mavi severmisiniz? KODU : <form> Işletim Sistemi:<BR> <INPUT TYPE=radio NAME=os VALUE=Win95>Windows 95 <INPUT TYPE=radio NAME=os VALUE=WinNT>Windows NT <INPUT TYPE=radio NAME=os VALUE=UNIX CHECKED>UNIX <INPUT TYPE=radio NAME=os VALUE=OS2>OS/2 CPU Tipi:<BR> <INPUT TYPE=radio NAME=cpu VALUE=Pentium>Intel Pentium <INPUT TYPE=radio NAME=cpu VALUE=Alpha CHECKED>DEC Alpha <INPUT TYPE=radio NAME=cpu VALUE=Bilinmiyor>Bilinmiyor </form> Web sayfasında görünümü: İşletim Sistemi: Windows 95 Windows NT UNIX OS/2 CPU Tipi: Intel Pentium DEC Alpha Bilinmiyor Kodu: <SELECT NAME="Mesai" Günleri> <OPTION SELECTED>Pazartesi <OPTION>Salı <OPTION>Çarşamba <OPTION>Perşembe <OPTION>Cuma </SELECT> Web sayfasında görünümü: Bu tanımdaki alanda default(seçili) değer Pazartesi'dir. Formlarda birden fazla satırı içeren bir text alanı tanımlanacaksa bu <textarea> ile belirtilir. Örnek: KODU: <form> <TEXTAREA NAME=Notlar ROWS=3 COLS=60></TEXTAREA> </form> Web sayfasındaki görünümü: Bu kodlama ile web sayfasında 3 satır ve 60 karakter genişliğinde bir alan tanımlanır. CGI için FORM Kullanımı Formlara bu şekilde kabaca bir bakmış olduk. Şimdi şu kodu inceleyelim. KODU : <form method=POST action="http://www.gazi.edu.tr/cgi-bin/konuk.pl"> <table><tr><td align=right> <p> E-mail addresi.? </td><td> <input type="text" name="email"> </td></tr><tr><td align=right> Adınız? </td><td> <input type="text" name="ad"></td></tr><tr> <td valign=top align=right> Notunuz. </td><td> <textarea name="izah" rows=3 cols=50></textarea><br> <input type=submit value="yaz"> <input type=reset value="sil"></td></tr> </table> </form> Web sayfasında görünümü: E-mail adresi..? Adınız? Notunuz. Yukarda ki kodlama da <table><tr><td align=right><p><br> gibi kodlamalar tamamen sayfanın daha iyi görünmesi için kullanılan html kodlarıdır.Bunları bir yana koyacak olursak cgi ve form komutlarını içeren kodlar şu biçimdedir; <form method=POST action="http://www.gazi.edu.tr/cgi-bin/konuk.pl"> E-mail addresi.? <input type="text" name="email"> Adınız? <input type="text" name="ad"> Notunuz. <textarea name="izah" rows=3 cols=50></textarea> <input type=submit value="yaz"> <input type=reset value="sil"> </form> İlk satırda form tanımı başlatılıyor ve aynı satırda cgi programına geçirilecek bilgilerin metodu ve tam URL adresi veriliyor. Daha açıkça ifade edecek olursak formda bulunan submit buton özelliğine kliklememiz halinde http://www.gazi.edu.tr/cgi-bin/ adresindeki konuk.pl isimli perl cgi programı çalıştırılır ve datalar POST metoduyla gönderilir. Peki gönderilecek datalar hangileridir? Bu datalar; email, ad ve izah değişkenleri(alan-adları) ve içerikleridir(değerler). email isimli değişkenin(alan-adının) içeriği o alana girdiğiniz değer yani e-mail adresi bilgisi, ad isimli değişkenin içeriği Ad ve Soyad bilgisi, izah isimli değişkenin içeriği ise yazdığınız notlardan oluşan değerdir. Değişken ve içerdikleri değerler server'a cgi programına gönderilir ve program tarafından gerektiği gibi değerlendirilir. Şimdi konuyu biraz daha açalım. Formlarda data iletişimi için GET ve POST metotlarından yararlanılır. Eğer GET metodu kullanılırsa, web sayfasındaki data (komut olarak eklenen veya form alanlarına girilen değerler) browser'a alınır. ? isaretiyle URL'ye eklenir. Örneğin"/cgibin/konuk.pl?ad=Ertan%20Turkmen&[email protected]&izah=basarilar"biçiminde). Bu değer QUERY_STRING değişkeni içinde tutulur ve cgi programa geçirilir. Data 256 karakterden uzun olamaz. GET metodu ile server'a gönderilen bilgi güvenlikten yoksundur. Üçüncü şahıslar tarafından tespit edilebilir. POST metodu kullanılmışsa forma girilen değerler ve alan-adlarından oluşan datalar standart girişi(STDIN) kullanarak serverdaki cgi programına gönderilir. Server ne kadar data okuması gerektiğini belirlemek için CONTENT_LENGTH çevre değişkenini kullanır, STDIN yoluyla girilen bu değerler toplu olarak tek bir string şeklinde buffer alanına alınır. Ör: read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'})). bu stringin uzunluğu CONTENT_LENGTH değişkenindedir. Programın işlenmesi sonucu çıktı olarak üretilen dataların ne tipte olacağı bilgisini ise CONTENT_TYPE çevre değişkeniyle belirtiriz. Bu çıktı tipleri html, gif, text gibi MIME tipleridir. GET metoduyla 256 karakterden fazla gönderilemezken POST metodu fazlasını kabul eder ve datalar daha güvenli bir şekilde server'a aktarılır. Metotla ilgili mutlaka bilmemiz gereken bu bilgilerden sonra tekrar formumuza dönelim ve formda bulunan alan-adları (ad,email gibi) ve içine girilen değerler (Ertan TURKMEN,[email protected] gibi) hep birlikte nasıl server'a gönderilir inceleyelim. Formda bulunan isimle ilgili text alanımızın adı ad idi. Biz bu alana Ertan Türkmen değerini, email isimli alana da [email protected] değerini girmiş olalım. Bu stringler alan-adı/değer çifti olarak şu biçimde serverdaki programa gönderilirler: ad=Ertan+Turkmen&[email protected] & işareti alan-adı ve değer çiftlerini ayırırken = karakteri ise alan-adı ile onun içindeki değer bilgisini ayırır + karakterine gelince bu karakter alan içindeki değerlerin boşluk kısmını temsil eder. Ayrıca <,> gibi karakterlerde hexadesimal olarak % işaretiyle birlikte ifade edilir. Örneğin,<[email protected]> ifadesi, %3Certan%40gazi.net%3E olarak cgi programına gönderilir. Bu gösterime URL Kodlama(URL Encoding) işlemi denir.(Not:URL=UniformResourceLocator). Çok kullanılan bazı karakterlerin kodları aşağıdadır. Karakter URL Kodu \t %09 \n %0A @ %40 & %26 / %2F ~ %7E ; %3B : %3A < %3C > %3E Peki bu gösterimi cgi nasıl normale döndürür yani decode eder?. İşte decode fonksiyonu içeren alt program örneği: sub URL_yi_coz{ $_ = shift; tr/+/ /; s/%(..)/pack('c', hex($1))/eg; return($_); } Bu örnekle tr satırında +, lar boşluğa çevrilir ve mesela Ertan+Turkmen, Ertan Turkmen şekline dönüşür. Bir alt satırda da % v.s. gibi özel ve hexadecimal kodlanmış karakterler atılarak string normale döndürülür. Bu işi pack fonksiyonunun özelliği yapar. 'c' hexadecimal gösterimin normal karakter stringine döneceğini temsil eder. $_ ise daha önceden de öğrendiğiniz gibi burada stringin tamamını ifade etmektedir.Bu alt program return($_); ifadesiyle normale döndürülmüş(decode edilmiş) stringi döndürür. (Not:Biz decode işlemini alt programda değil normal program akışında yapacaksak $deger =~ tr/+/ /; $deger =~ s/%(..)/pack("C", hex($1))/eg; şeklinde kodlayabiliriz. Bu durumda stringin tamamı $deger değişkenindedir). Örnek Program: Bir web sayfasından girilen ad, e-mail ve not bilgilerini alıp, bunu browser'ınıza html sayfası olarak basan bir cgi yazalım adını ornek2.pl koyalım. İşte kodu: #!/usr/bin/perl print "Content-type:text/html\n\n"; # ornek2.pl programının çıktısı html sayfası olacak demektir #bir üst satırın boş olması önerilir. #Eğer text dosya halinde çıktı istersek Content-type tanımı : # Content-type: text/plain\n\n biçimindedir. #sondaki 2 satır sonu karakteride çıktı düzeni için gereklidir(\n\n) read(STDIN, $gecici_alan, $ENV{'CONTENT_LENGTH'}); # giriş (STDIN) den gelen veriler $gecici_alan adlı bir skalar değişkene #aktarıldı @alan_deger_ciftleri = split(/&/, $gecici_alan); #her bir alan-adı/değer çifti ayrı ayrı alan_deger_ciftleri dizisine konuldu foreach $alan_deger (@alan_deger_ciftleri) { # her bir alan-adı/değer çiftinin her biri tek tek $alan_deger değişkenine alınıyor ($alan, $deger) = split(/=/, $alan_deger); #alan-adı ,$alan değişkenine;değer ise $deger değişkenine atandı $deger =~ tr/+/ /; # + karakteri boşluk karakterine dönüştü $deger =~ s/%(..)/pack("C", hex($1))/eg; # üst satır aşağıdaki gibi de kodlanabilir ama uzatmaya gerek yok # $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1)) # hexadecimal karakterlerde normale dönüştürülüp tüm string decode edildi $FORM{$alan} = $deger; #string alan-adı ve değer olarak, #FORM isimli bileşik diziyi oluşturuyor } print "<html><head>"; print "<title>örnek2</title>"; print "</head>"; #web sayfasının başlangıç tanımları yapıldı print "<body bgcolor=ffffff>"; #sayfanın zemin rengi beyaz olarak tanımlandı ve bastırıldı print "<center><table border=1 bordercolor=000055 bgcolor=ff7777> <tr><td>"; #düzgün görüntü için tablo tanımlandı.tablonun zemin rengi,kenarlık #kalınlığı ve rengi de tanımlandı ve bastırıldı print "</center><center><h3><ul>Gönderilen Bilgileri Aşağıya Yazdım</ul></h2>\n"; # başlık kısmı bastırıldı print "</center><p align=center><br>\n"; # değerlerin bastırılması için ayar yapıldı ortalı olarak bastırılacak foreach $key (keys(%FORM)) { # her bir alan-adı ve değeri çifti tek tek alınıyor print "$key = $FORM{$key}<br>", # ve bastırılıyor } print "</p><br></td></tr></table></body></html>"; # sayfa sonu tanımları tamamlandı..Kodlama tamamlandı! Şimdi bu perl cgi programını çalıştıracak web sayfasını da kodlayalım. KODU : <html><head><title>ornek2</title></head> <body> <table border=1 bordercolor=dc6000 bgcolor=337733><tr><td> <form action="http://www.gazi.edu.tr/cgi-bin/ornek2.pl" method="POST"> <pre> Adınız : <input type="text" name="ad"> E-mail : <input type="text" name="email"> Notunuz: <input type="text" name="not"> </pre> <input type="submit" value="Yolla"> <input type="reset" value="Sil"> </form> </td></tr></table> </body> </html> Bu sayfa Browserınızda şöyle gözükecektir. Adınız : E-mail : Notunuz: Yukarıdakiforma ait, email alanına : [email protected], not alanına : Basarilar, ad alanına ise Ertan Turkmen girelim ve Yolla tuşunu klikleyelim. Browser ekranında aşağıdaki görüntü varsa cgi programınız doğru çalışmış demektir. Gönderilen Bilgileri Aşağıya Yazdım email = [email protected] not = Basarilar ad = Ertan Turkmen Siz bu örnekle sadece 3 değer girdiniz ama çok fazla sayıda da alan-adı tanımlar ve onlara değerler girebilirdiniz. Program yine başarıyla çalışırdı. Çevre Değişkenleri (Environment Variables): cgi programlarıyla çevre değişken ve değerlerine erişmek mümkündür. Bir kısmı aşağıdadır. SERVER_SOFTWARE : Kullanılan Web server versionu. REMOTE_ADDR : client (Browser'dan çalıştıranın) IP adresi. REMOTE_HOST : client tam domain adı. QUERY_STRING : Eğer GET metodu kullanılmışsa URL encoded string. (Aranacak kelime veya alanadı/alandeğeri çifti içerir) HTTP_USER_AGENT : Kullanıcının Browser'ı.(netscape,explorer v.s.) CONTENT_LENGTH : String uzunluğu(byte). CONTENT_TYPE : MIME tipi (text,html,gif) DOCUMENT_ROOT : Server dökümanları için ana dizin (/...httpd/htdocs) REQUEST_METHOD : client tarafından gonderilen istek metodu (GET veya POST). SCRIPT_NAME : CGI scriptin URL'si ve adı SERVER_NAME : Server adı (DNS host adı) Çevre değişkenleri bilgilerini elde eden bir test programı yazalım. Adı text2.pl olan programın çıktısı web sayfasına olup kodu ise aşağıdadır. #!/usr/bin/perl print "Content-type: text/html\n\n"; print <<"bas"; <html> <BODY> <TITLE> HTML ÇIKTISI </TITLE> <p> <H1> CEVRE DEGISKENLERI </H1> <UL> <LI>DOCUMENT_ROOT = <B> $ENV{'DOCUMENT_ROOT'}</B> <LI>GATEWAY_INTERFACE = <B> $ENV{'GATEWAY_INTERFACE'}</B> <LI>HTTP_ACCEPT = <B> $ENV{'HTTP_ACCEPT'}</B> <LI>PATH = <B> $ENV{'PATH'} <LI>QUERY_STRING = <B> $ENV{'QUERY_STRING'}</B> <LI>REMOTE_ADDR = <B> $ENV{'REMOTE_ADDR'}</B> <LI>REQUEST_METHOD = <B> $ENV{'REQUEST_METHOD'}</B> <LI>SCRIPT_NAME = <B> $ENV{'SCRIPT_NAME'}</B> <LI>SERVER_NAME = <B> $ENV{'SERVER_NAME'}</B> <LI>SERVER_SOFTWARE = <B> $ENV{'SERVER_SOFTWARE'}</B> <LI>SERVER_PORT = <B> $ENV{'SERVER_PORT'}</B> <LI>SERVER_PROTOCOL = <B> $ENV{'SERVER_PROTOCOL'}</B> </UL> </BODY> </HTML> bas programın çıktısı ise aşağıdadır. ÇEVRE DEĞİŞKENLERİ · DOCUMENT_ROOT = /home/httpd/htdocs · GATEWAY_INTERFACE = CGI/1.1 · HTTP_ACCEPT = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/xcomet, application/vnd.ms-powerpoint,application/vnd.ms-excel, application/msword, application/pdf, */* · PATH = /sbin:/usr/sbin:/bin:/usr/bin · REMOTE_ADDR = 192.168.100.9 · REQUEST_METHOD = GET · SCRIPT_NAME = /cgi-bin/test2.pl · SERVER_NAME = www.gazi.edu.tr · SERVER_SOFTWARE = Apache/1.3.3 (Unix) (Red Hat/Linux) · SERVER_PORT = 80 · SERVER_PROTOCOL = HTTP/1.1 FORM MAIL KULLANIMI ornek2.pl programıyla bazı bilgileri server'a göndermiştik. Şimdi aynı bilgileri mail yoluyla [email protected] isimli kullanıcıya (kendimize) mail ile gönderme programını inceleyelim. Bu internette çok yaygın kullanılır. Form mail olarak bilinir. Amaç genelde sayfa veya server ile ilgili ziyaretçi önerilerini almaktır. Web sayfamızdaki form hatırlarsanız aşağıdaki gibiydi. Adınız : E-mail : Notunuz: Bu sayfaya girilen değerleri işleyecek olan programımızın adı fmail.pl olsun. Yani form tanımındaki İlgili satır tanımı şöyle olacak: <form action="http://www.gazi.edu.tr/cgi-bin/fmail.pl" method="POST"> Program ayrıca Notunuz:(not) kısmına bilgi girilmez ise bu alana mutlaka bilgi girilmesi için uyarsın. Şimdi bu perl cgi programını (fmail.pl) kodlayalım. #!/usr/bin/perl $sysmailprg = '/usr/sbin/sendmail -t'; $alan = '[email protected]'; print "Content-type: text/html\n\n"; print "<HTML>\n<HEAD>\n<TITLE>Teşekkürler</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#CC0000\">\n"; read(STDIN, $gecici_alan, $ENV{'CONTENT_LENGTH'}); if ( $gecici_alan eq '\0') { exit(0) }; @ciftler = split(/&/, $gecici_alan); foreach $cift (@ciftler) { ($isim, $deger) = split(/=/, $cift); $deger =~ tr/+/ /; $deger =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$isim} = $deger; } &bos_cevap unless $FORM{'not'}; # not alanına bir şey girilmemişse #devreye girecek altprogram # mail alanın (burada [email protected]) alacağı mesajlar open (MAIL, "|$sysmailprg $alan") || ("$sysmailprg bulunamadı.!\n"); print MAIL "From: $FORM{'email'} ($FORM{'ad'})\n"; print MAIL "Subject: Önerileri içeren Notlar\n\n"; print MAIL "\n\n-----------------------------------------------------------$ print MAIL " $FORM{'not'}\n\n"; print MAIL "\n\n-----------------------------------------------------------$ print MAIL "Browser: $ENV{'HTTP_USER_AGENT'}\n"; print MAIL "Geldiği makina: $ENV{'REMOTE_HOST'}\n"; close (MAIL); # mail gönderenin browser'ına çıkan mesaj print "<p><br><center><H3>Notunuzu aldım ve değerlendireceğim</H3><p><br>"; print "<B>İlginize teşekkürler.<PALIGN=\"CENTER\">\n\n"; print "<A HREF=\"mailto:ertan\@sirius.gazi.edu.tr\">Ertan Turkmen</A></P>\n\n"; print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; print "</center></BODY>\n</HTML>\n"; #not alanı boş geçilirse devreye girecek olan alt program kodu sub bos_cevap { print "<center><p><br><b>Hic bir not yazmadiniz ... "; print "Yeniden Deneyiniz !</b>\n"; print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; exit; } Şimdi de yukardaki forma verileri girip Yolla tuşuna basalım. Program çalışacak ve e-mail olarak kullanıcıya ([email protected]) gidecek.E-mail mesajı alıcı tarafından şu şekilde okunacaktır. Date: Tue, 1 Jan 1999 16:25:55 +0200 From: Atilla Usenmez <[email protected]> Subject: Önerileri içeren Notlar -----------------------------------------------------------Başarılı Çalışmalarınızın devamını dilerim. Kolay Gelsin. -----------------------------------------------------------Browser : Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt) Geldiği makina: ve gönderenin browser sayfasına çıkan mesaj ise aşağıdaki gibi olacaktır. Notunuzu aldım ve değerlendireceğim İlginize teşekkürler. Anket Formları İnternette bolca rastladığımız örneklerden biri de anket formudur.Bu konuyu da görelim. Formumuz aşağıdaki görünümde olsun. Adınız: Bu sene kim şampiyon olacak ? Beşiktaş Trabzonspor Galatasaray Fenerbahçe ve KODU : <form action="http://www.gazi.edu.tr/cgi-bin/ornek8.pl" method="POST"> Adınız:<input type="text" name="ad" size=25><br> Bu sene kim şampiyon olacak ? <br> <input type="radio" name="secim" value=1> Beşiktaş <input type="radio" name="secim" value=2> Trabzonspor <input type="radio" name="secim" value=3> Galatasaray <input type="radio" name="secim" value=4> Fenerbahçe <br><input type="submit" value="Seçimini Gönder"> </form> Bu formu işleyecek programımızın (ornek8.pl) kodu ise : #!/usr/bin/perl print "Content-type:text/html\n\n"; read(STDIN, $gecici_alan, $ENV{'CONTENT_LENGTH'}); @alan_deger_ciftleri = split(/&/, $gecici_alan); foreach $alan_deger (@alan_deger_ciftleri) { ($alan, $deger) = split(/=/, $alan_deger); $deger =~ tr/+/ /; $deger =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$alan} = $deger; } print "<HTML>\n<HEAD>\n<TITLE>Teşekkürler</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#CC0000\">\n"; print "<p><br><center><H3>Değerlendirme Sonucu !!!</H3><p><br>"; print "<PALIGN=\"CENTER\">\n\n"; print "SAYIN $FORM{'ad'}<br>"; %kim = ( 1 => "Beşiktaş", 2 => "Trabzonspor", 3 => "Galatasaray", 4 => "Fenerbahçe" ); print "$FORM{'secim'}.Seçeneği işaretleyerek,<br>"; print "$kim{$FORM{'secim'}} Futbol Takımını seçtiniz<br>"; print "Anketimize katıldığınız için teşekkürler..<br>"; print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; print "</center></BODY>\n</HTML>\n"; Formu doldurup Seçimini Gönder butonuna klikleyiniz ve daha sonra nasıl çalıştığını inceleyiniz. Daha kapsamlı bir anket formu. Web sayfasında görünümü: Adınız: Bu sene kim şampiyon olacak ? Beşiktaş Trabzonspor Galatasaray Fenerbahçe Şu ana kadar hangi şehirleri gördünüz ? Ankara İstanbul İzmir Trabzon Bursa Adana Van En sevdiğiniz sanatçı ? FORMUN KODU: <table bgcolor=ff3300><tr><td bgcolor=ffffcc> <form action="http://www.gazi.edu.tr/cgi-bin/ornek11.pl" method="POST"> Adınız:<input type="text" name="ad" size=50><br> <p> Bu sene kim şampiyon olacak ? <br><table><tr> <td> <input type="radio" name="secim" value=1> Beşiktaş <input type="radio" name="secim" value=2> Trabzonspor</td> <td> <input type="radio" name="secim" value=3> Galatasaray <input type="radio" name="secim" value=4> Fenerbahçe</td> </tr></table><hr size=1 color=#000055> Şu ana kadar hangi şehirleri gördünüz ? <br><table><tr><td> <input type="checkbox" name="ank" value=1> Ankara<br> <input type="checkbox" name="ist" value=1> İstanbul<br> <input type="checkbox" name="izm" value=1> İzmir<br> <input type="checkbox" name="tra" value=1> Trabzon<br></td><td> <input type="checkbox" name="bur" value=1> Bursa<br> <input type="checkbox" name="ada" value=1> Adana<br> <input type="checkbox" name="van" value=1> Van<br> </td></tr></table> <hr size=1 color=#000055> En sevdiğiniz sanatçı ? <select name="sanat"> <option value=0 selected>Sanatçı Listesi <option value=1>Barış MANÇO <option value=2>Cem KARACA <option value=3>Müslüm GÜRSES <option value=4>Nadide SULTAN <option value=5>Murat KEKİLLİ <option value=6>Küçük İBO </select> <hr size=1 color=#000055> <br><input type="submit" value="Seçimini Gönder"> </form> Bu formu değerlendiren programın kodu ise aşağıdadır.Formu doldurup yollayınız ve çalısmasını inceleyiniz. ornek11.pl #!/usr/bin/perl print "Content-type:text/html\n\n"; read(STDIN, $gecici_alan, $ENV{'CONTENT_LENGTH'}); @alan_deger_ciftleri = split(/&/, $gecici_alan); foreach $alan_deger (@alan_deger_ciftleri) { ($alan, $deger) = split(/=/, $alan_deger); $deger =~ tr/+/ /; $deger =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$alan} = $deger; } print "<HTML>\n<HEAD>\n<TITLE>Teşekkürler</TITLE>\n</HEAD>"; print "\n\n\n"; print "<p><br><center><H3>Değerlendirme Sonucu !!!</H3><p><br>"; print "<PALIGN=\"CENTER\">\n\n"; print "SAYIN $FORM{'ad'}<br>"; %takim = ( 1 => "Beşiktaş", 2 => "Trabzonspor", 3 => "Galatasaray", 4 => "Fenerbahçe" ); print "$FORM{'secim'}.Seçeneği işaretleyerek,<br>"; print "$takim{$FORM{'secim'}} Futbol Takımını seçtiniz<br>"; %kim=( "ank" => "Ankara", "ist" => "İstanbul", "izm" => "İzmir", "tra" => "Trabzon", "bur" => "Bursa", "ada" => "Adana", "van" => "Van"); print "Gördüğünüz Şehirler<br>\n"; foreach $key (keys %kim) { if ($FORM{$key} == 1) { # 1 seçtikleriniz 0 seçmediklerinizdir print "$kim{$key}<br>\n"; } } %sanatci = ( 1 => "Baris MANCO", 2 => "Cem KARACA", 3 => "Muslum GURSES", 4 => "Nadide SULTAN", 5 => "Murat KEKiLLi", 6 => "Kucuk iBO" ); print "Seçtiğiniz Sanatçı: $sanatci{$FORM{'sanat'}}<br>"; print "Anketimize katıldığınız için teşekkürler..<br>"; print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; print "</center></BODY>\n</HTML>\n"; CGI kullanarak sistemdeki dosyalarla çalışma Örneklerimizde program çıktılarımız Browser'ımızın sayfaları idi. Html veya text sayfası olan bu çıktıları browser'da görüntülemek yerine sistemdeki bir dosyaya yazmak isteyebilir veya dosyadan okutup browser'a yazmak isteyebiliriz. Şimdi bu durumlarda ne yapacağımızı görelim. Bu arada konuya başlarken daha evvel işlenen Dosyalar konusunu gözden geçiriniz. Yine kolaylık olsun diye aynı form ve örnekten hareket edelim. Önceki formdaki bilgileri bu defa bir dosyaya yazdıralım. Ayrıca browser'a da Işlem Tamam ! mesajı yollansın. Üzerinde işlem yapacağımız dosyanın adı dosyam.dat ve onu temsil eden dosya belirteninin adı ise DOSYAM olsun. Bu dosyayı önce herkesin yazabileceği bir modda açmamız gerekir. Dosyayı herhangi bir yerde açabiliriz ama biz yine cgi-bin dizininde açalım. Bu işlemi yapmak için önce; touch dosyam.dat (bu komutla dosya oluşturuluyor) komutunu, daha sonrada chmod 777 dosyam.dat (bu komutla herkese dosya üzerinde tüm haklar veriliyor) komutunu girmemiz gerekir. Şimdi önceki örneğimiz olan ornek2.pl üzerinde değişiklik yapalım. Hatırlarsanız ornek2.pl ile web sayfasındaki formdan (aşağıda tekrar göreceksiniz) girilen ad,email ve not bilgileri alınıp sisteme yollanıyor ve bu bilgiler browser web sayfasına yazdırılıyordu. Biz sadece bu son kısmı düzeltir ve browser sayfası yerine sistemdeki dosyam.dat a yazdırırsak istediğimiz gerçekleşecektir. Yazacağımız perl program adı ornek3.pl olsun (tabii bu dosyada cgi-bin de olacak). Şimdi kodlayalım. #!/usr/bin/perl print "Content-type:text/plain\n\n"; read(STDIN, $gecici_alan, $ENV{'CONTENT_LENGTH'}); @alan_deger_ciftleri = split(/&/, $gecici_alan); foreach $alan_deger (@alan_deger_ciftleri) { ($alan, $deger) = split(/=/, $alan_deger); $deger =~ tr/+/ /;# + karakteri boşluk karakterine dönüştü $deger =~ s/%(..)/pack("C", hex($1))/eg; # $deger =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1)) $FORM{$alan} = $deger; } { open (DOSYAM, ">>./dosyam.dat") || die ("HATALI iSLEM..!"); print DOSYAM "$FORM{'ad'}:$FORM{'email'}:$FORM{'not'}\n"; # yukarda bulunan : karakteri her alanı bir diğerinden ayırır. # bu karakteri, alan ayıracı olarak kendimiz belirledik close(DOSYAM); } print "<HTML>\n<HEAD>\n<TITLE>Teşekkürler</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFFFFF\" LINK=\"#CC0000\">\n"; print "<p><br><center><H3>İşlem Tamam !!!</H3><p><br>"; print "<PALIGN=\"CENTER\">\n\n"; print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; print "</center></BODY>\n</HTML>\n"; Şimdi aşağıdaki formu dolduralım ve yollayalım. Form tanımındaki form adı ile ilgili satırın tanımı şöyle olacak: <form action="http://www.gazi.edu.tr/cgi-bin/ornek3.pl" method="POST"> Sonuçta bilgilerin sistemde bulunan dosyam.dat ' a yazıldığını ve her bir veri alanının da birbirinden : karakteri ile ayrıldığını göreceksiniz. Adınız : E-mail : Notunuz: Dosyalardan Okuma Dosyalara yazma işlemini sanırım anladık.Şimdi sıra sistemdeki dosyadan bilgileri almak(okutmak) ve bu bilgileri değerlendirmekte... Bir önceki konuda formdan yolladığımız bilgiler dosyam.dat adlı dosyaya yazmıştı.Şimdi bu dosyadan okutma yaparak hem okuma işlemini hem de bir önceki yazdırma işleminin doğruluğunu test etmiş olacağız. Aşağıdaki örnekte dosyam.dat dan okunan satırlar(kayıtlar) sırayla bir browser'ın sayfasına yazdırılmaktadır. İnceleyelim. Programın adı ornek4.pl olsun. #!/usr/bin/perl print "Content-type:text/html\n\n"; { print "<HTML>\n<HEAD>\n<TITLE>KAYITLAR</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFdd00\" LINK=\"#CC0000\">\n"; open (DOSYAM, "./dosyam.dat") || die ("HATALI iSLEM..!"); print "<p><br><center><H4>Dosyaya girilen kayıtlar aşağıdadır !</H4><p><br>"; print "<PALIGN=\"CENTER\">\n\n"; @tumkayitlar = <DOSYAM>; close(DOSYAM); foreach $herbirkayit (@tumkayitlar){ chomp($herbirkayit); print "$herbirkayit<br>\n"; } } print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; print "</center></BODY>\n</HTML>\n"; Şimdi bu programı çalıştıralım Bir de daha farklı bir çıktısı olan bu programı deneyiniz ve farkı inceleyip anlayınız. Program kodu aşağıdadır.(ornek5.pl) #!/usr/bin/perl print "Content-type:text/html\n\n"; { print "<HTML>\n<HEAD>\n<TITLE>KAYITLAR</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFdd00\" LINK=\"#CC0000\">\n"; open (DOSYAM, "./dosyam.dat") || die ("HATALI iSLEM..!"); print "<p><br><center><H4>Dosyaya girilen kayıtlar aşağıdadır !</H4><p><br>"; print "\n\n"; print "<table bgcolor=ffffff border=1 bordercolor=dc6000><tr>"; # Çıktının düzenli olması #için table tanımları yapılıyor @adlar = ("AD VE SOYAD","E-MAIL ADRESI","BIRAKILAN NOT"); #çıktı #başlıkları oluşturuluyor foreach $ad (@adlar) { print "<td bgcolor=ff3300>"; print "$ad"; # başlıklar bastırılıyor print "</td>"; } print "<br>\n\n"; print "</tr>"; @tumkayitlar = <DOSYAM>; close(DOSYAM); foreach $kayit (@tumkayitlar){ chomp($kayit); @degerler = split(/:/, $kayit); print "<tr>"; # alan içerikleri bastırılıyor print "<td>$degerler[0]</td>"; print "<td>$degerler[1]</td>"; print "<td>$degerler[2]</td>"; print "</tr>"; } print "</tr></table>\n"; print "<FORM>\n"; print "<INPUT onclick=history.go(-1) type=button value=Geri>\n"; print "</FONT></FORM></center><p><br>\n"; print "</center></BODY>\n</HTML>\n"; } Dosyada String Arama String bildiğiniz gibi içinde her türlü karakterleri barındırabilen karakterler dizisidir(boşluk v.b dahil). Dosyalara yazma,okuma örneklerimizden sonra şimdi de bir dosyanın içerisinde belli bir string aratma konusunu inceleyelim.Yine konuyu daha iyi kavramak için daha önceki örneklerimize sadık kalacağız.Onceki örneklerde hatırlarsanız dosyam.dat isimli dosya üzerinde çalışmıştık yine aynı dosyada bu sefer string (metin) taraması yapacağız. Dosyada arama yaptırmak için daha önce gördüğümüz konulardan faydalanarak (özellikle patternler)her bir kayıtta örnek stringi tarayacağız. Bu arada sadece metin aratacağımız için GET metodunu kullanacağız. Şimdi web sayfasında görünümü aşağıdaki gibi olan bir form tanımlayalım. Arayacağınız kelimeyi giriniz : KODU: <table width=60% border=1 bordercolor=#000055 bgcolor=#ff7700> <tr><td> <form action="http://www.gazi.edu.tr/cgi-bin/ornek6.pl" method="GET"> Aradığınız kelimeyi giriniz : <input type="Text" name="kelime"> <input type="submit" value="Ara !"> <input type="reset" value="Sil"> </form> </td></tr> </table> Yukardaki forma aratacağımız kelimeyi girip Ara ! tuşuna basınca, formun action alanında tanımlandığı üzere ornek6.pl programı çalıştırılacak ve yine o programda adı verilen dosyam.dat dosyasında kelime taranacak ve sonuclar listelenecektir. Programın kodu ise aşağıdadır.Formu doldurarak çalışmasını görünüz ve aşağıdaki kodu inceleyiniz. Bu arada taramada kolaylık olsun diye dosyam.dat daki bazı kelimeleri vereyim. Sevgi kaya(boşluk dahil),Atilla,Sevgi,sev,ali ... Bu kelimeleri sorgulayabilirsiniz. #!/usr/bin/perl print "Content-type:text/html\n\n"; $veriler = $ENV{'QUERY_STRING'}; #formdan alan-adı ve içeriği geldi ve aktarıldı #standart dışı karakterler düşünülerek aşağıdaki 2 satır eklendi $veriler =~ tr/+/ /; $veriler =~ s/%(..)/pack("C",hex($1))/eig; # string normale dönüştü ($alan, $deger) = split(/=/, $veriler); #alan-adı ve içeriği ayrıştırıldı $deger =~ tr/a-z/A-Z/; #buyuk harfe cevrildi..Amac:formdan nasıl girilirse girilsin farketmesin $deger =~ s/\+/ /g; # + işareti boşluğa dönüştü print "<HTML>\n<HEAD>\n<TITLE>TARAMA SONUCLARI</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFdd00\" LINK=\"#CC0000\">\n"; print "Sorgulanan Kelime:$deger<hr nosize>"; print "<center>"; print "<table width=100% bgcolor=33ff00 border=1 bordercolor=ff0000>"; # düzemli çıktı amacıyla web sayfası tanımlandı open (DOSYAM, "./dosyam.dat") || die ("HATALI iSLEM..!"); @tumkayitlar = <DOSYAM>; close(DOSYAM); @adlar = ("AD VE SOYAD","E-MAIL ADRESI","BIRAKILAN NOT"); #sistemdeki dosya açıldı kayıtlar diziye alındı Başlıklar ise bastırılmak uzere bir baska diziye alındı foreach $ad (@adlar) { print "<td bgcolor=ff3300>"; print "$ad"; # başlıklar bastırıldı print "</td>"; } print "<br>\n\n"; print "</tr>"; foreach $kayit (@tumkayitlar){ chomp($kayit); $kayit=~ s/\s*##.*$//; $kayit =~ tr/a-z/A-Z/; # dosyam.dat kayıtları normal olmayan karakterlerden #arındırılıp buyuk harfe cevrildi if ($kayit =~/$deger/){ #formdan gelen taranacak kelime kayıttamı? Evet ise aşağıya geç @degerler = split(/:/, $kayit); #kaydı alanlarına böl(ad,email,not) print "<tr>"; print "<td>$degerler[0]"; print "<td>$degerler[1]"; print "<td>$degerler[2]"; # kelimenin bulunduğu kayıt (Alanlar ayrı ayrı olmak üzere) bastırıldı print "</tr>"; } } print "</table>"; print "</center></body></html>\n"; #web sayfası sonu Dosyada tam kelime sorgulama Bir önceki örnekte string taraması yapan programı inceledik.Biliyorsunuz şunların her biri string örnekleridir;"ali",ali ak","0lp96?" v.b. Bunlar anlamlı yada anlamsız olabilir.Bu defa herhangi bir stringi değil bir kelimeyi, taranan dosyada tam örneği varsa bulan bir program kodlayalım. Formumuz önceki form ile aynı olsun.Sadece program adını ornek6.pl değil ornek7.pl olarak düzelteceğiz.Aşağıdaki formda bu düzenlemeyi yaptım.Kodu ise formun altındadır. Aradığınız kelimeyi giriniz : KODU: <table width=60% border=1 bordercolor=#000055 bgcolor=#ff7700> <tr><td> <form action="http://www.gazi.edu.tr/cgi-bin/ornek7.pl" method="GET"> Aradığınız kelimeyi giriniz : <input type="Text" name="kelime"> <input type="submit" value="Ara !"> <input type="reset" value="Sil"> </form> </td></tr> </table> Yukardaki forma aratacağımız kelimeyi girip Ara ! tuşuna basınca,ornek7.pl programı, dosyam.dat dosyasında(bir önceki programda da kullanmıştık) aranan tam kelime örneğini tarar ve sonucu listeler.Formu doldurarak çalışmasını görünüz ve aşağıdaki kodu inceleyiniz. Bu arada aranacak kelime tam kelime olmalıdır.Kelimeden sonta yanlışlıkla boşluk dahi girseniz Kelimeyi bozmuş olacağınızdan sorgulama başarısız olur.Örneğin atilla yazıp boşluk tuşuna da dokunursanız kelimeniz atilla+ olacaktır ve dosyam.dat dosyasındaki atilla kelimesine uymayacağından sorgulama başarısız olacaktır.Amacımız tam kelime sorgulaması olduğundan bu derece katı önlem aldık. Örnek7.pl #!/usr/bin/perl print "Content-type:text/html\n\n"; $veriler = $ENV{'QUERY_STRING'}; #formdan girilen alan-adı ve içeriği #standart dışı karakterler düşünülerek aşağıdaki satırlar eklendi $veriler =~ tr/+/ /; $veriler =~ s/%(..)/pack("C",hex($1))/eig; ($alan, $deger) = split(/=/, $veriler); $deger =~ tr/a-z/A-Z/; $deger =~ s/\+/ /g; print "<HTML>\n<HEAD>\n<TITLE>TARAMA SONUCLARI</TITLE>\n</HEAD>"; print "\n\n<BODY BGCOLOR=\"#FFdd00\" LINK=\"#CC0000\">\n"; print "Sorgulanan Kelime:$deger<hr nosize>"; if ($deger eq "" or $deger =~ /^\s+/){ #Boş geçilmesin print "<h1>Sorgulanacak Kelime Girilmedi ..!<h1>"; exit; } print "<center>"; print "<table width=100% bgcolor=33ff00 border=1 bordercolor=ff0000>"; open (DOSYAM, "./dosyam.dat") || die ("HATALI iSLEM..!"); @tumkayitlar = <DOSYAM>; close(DOSYAM); @adlar = ("AD VE SOYAD","E-MAIL ADRESI","BIRAKILAN NOT"); foreach $ad (@adlar) { print "<td bgcolor=ff3300>"; print "$ad"; print "</td>"; } print "<br>\n\n"; print "</tr>"; $test=0; $kontrol=0; foreach $kayit (@tumkayitlar) { chomp($kayit); @degerler = split(/:/, $kayit); #Dosyadan diziye aktarılıyor sonradan bu diziden bastırılacak $kayit=~ s/\s*##.*$//; #kayıt lüzumsuz karakterlerden ayıklandı $kayit =~ tr/a-z/A-Z/; #kayıt büyük harfe çevrildi @kelimeler = split(/[\t ]+/, $kayit); #tab ve boşluklar varsa kayıt oradan bölündü ve diziye #kondu ve tam kelimeye erişim tedbirleri tamamlandı foreach $tam (0..$#kelimeler) { if (@kelimeler[$tam] =~ /\b$deger\b/) #formdan gelen kelimenin tam örneği varmı? { $test=1; $kontrol=1; last; #gerekli kontrol değişkenleri ayarlandı ve bu döngüden çıkıldı } } if ($kontrol == 1){ # kelime bulundu ve tüm kayıt bastırılıyor print "<tr>"; print "<td>$degerler[0]</td>"; print "<td>$degerler[1]</td>"; print "<td>$degerler[2]</td>"; print "</tr>"; $kontrol=0; } } if ($test == 0){ print "<tr>"; print "<td>Aranan KelimeBulunamadi..</td>"; print "</tr>";} print "</table>"; print "</center></body></html>\n";