Bu uygulama, aslında bir misilleme uygulaması olacak. Bu uygulamada biz, hem while kullanarak dosya okumayı hem de while ile case yapılarını birleştirerek dosya içerisinden bir şeyleri aramayı öğreneceğiz. Bu uygulamaya misilleme uygulaması dememin sebebi, aslında bunları iki basit komutla yapabilir olmamızdan kaynaklanıyor. Yani bu uygulamanın amacı, bunları daha uzun yollarla yaparak pratik yapmaktır.
Normal şartlarda bir dosya okumak için 'cat' komutunu kullandığımızı biliyorsunuz; nasıl olduğuna bakalım. Öncelikle, içerisinde bir şeyler yazan bir metin dosyası oluşturalım ve ismini 'deneme.txt' koyalım.

Daha sonra bunu 'cat' ile okuyalım.

Evet, dosyanın içeriğini başarılı bir şekilde okuduk. Peki, bunu while ile yapalım.
Bunun için daha önce gördüğümüz 'read' komutunu kullanacağız. while anahtar kelimesini verdikten sonra herhangi bir koşul falan yazmıyoruz. Sadece 'read' diyoruz ve bir değişken ismi belirliyoruz. Daha sonraki iskelet aynı; 'do' diyoruz. Fakat burada söylediğimiz şey; "file isimli değişken okunduğu sürece yap".

Bunu yaptıktan sonra bunu yazdırmamız lazım, öyle değil mi? O yüzden 'echo $file' şeklinde bir komut verebiliriz.

Son olarak 'done' deyip çalıştıracağız. Fakat ufak bir ekleme yapacağız.

done < deneme.txt şeklinde bir komut verdik. Bu noktada, biraz önce 'read file' diyerek okuduğumuz dosyanın ne olacağını burada belirliyoruz. Yani bu kod parçasında şunu demiş olduk: "deneme.txt dosyasını oku ve yazdır". Şimdi, çalıştırıp bakalım.

'done' deyince döngü bitiyordu, evet. Ancak < işaretiyle, dosya ismini bu döngüye bağlamış ve döngü içerisindeki kodları bu dosya için uygulamış oluyoruz.
Dosyadan Kelime Seçmek
Bu kısımda, biraz önceki deneme.txt dosyasından cyberworm kelimesini bulacağız. Eğer kelime mevcutsa onu bize gösterecek ama mevcut değilse bir şey yazmayacak. Bunun için 'cat' komutu ile birlikte 'grep' komutunu kullanacağız. Grep, 'tutmak, kavramak' anlamına gelir. Nasıl kullanıldığını inceleyelim.

İlk önce içerisinden kelime veya cümle arayacağımız dosyayı 'cat' ile okumamız lazım. Bunun için 'cat deneme.txt' komutunu verdik. Hemen sonrasında 'pipe - boru' işareti dediğimiz işareti oraya koyuyoruz (AltGr + Alt tire). Daha sonra arayacağımız şeyi yazıyoruz (grep <aranacak şey>).
Bu komutu verdikten sonra dosya tarandı ve grep'e verdiğimiz argüman bulundu. Eğer bulunamasaydı herhangi bir çıktı alamazdık.
Şimdi, bunu uzun yolla yapalım.
İlk önce, aradığım şeyin kaçıncı satırda olduğunu daha net görebilmek için line isimli bir değişken tanımlayıp ona '1' değerini veriyorum. Çünkü birinci satırdan başlayacak.

Dosya içeriğini okumak adına bir döngüye ihtiyacımız var. Bu yüzden hemen biraz önceki gibi bir while döngüsü açıyorum.

Yukarıdaki kod, dosyayı okumamıza olanak tanıyor. Ancak biz, dosyanın içerisini aramak ve istediğimiz bir kelimeyi veya cümleyi bulmak istiyoruz; grep gibi olsun istiyoruz. Bunun için kullanıcıya neyi, nerede aradığını soralım.

İlk önce ne aradığını, sonra aradığı şeyin yerini (lokasyonunu) ve son olarak dosyanın ismini istedik. Daha sonra 'cd' diye bir komut verdik ve kullanıcı hangi lokasyonda olursa olsun ana klasöre insin istedik. Sonrasında gelen 'cd $location' komutu ile, kullanıcının girdiği lokasyona gidebiliyoruz. Eğer 'cd' demeseydik kullanıcı, çok ters bir lokasyonda olabilirdi ve bir türlü bahsettiğimiz o lokasyona gidemezdi. O yüzden öne ana klasöre indik.
Şimdi ise bence aradığımızı bulabilmek için 'case - esac' kullanabiliriz. Deneyelim.

while döngüsünün içine, case - esac ifademi açtım. 'case $file in' diyerek aslında while içerisinde okuduğumu 'file' değişkenine hitap ediyoruz.
Hemen alt satıra inip bir TAB boşluk bıraktıktan sonra biraz önce kullanıcıdan istediğimiz kelimeyi arayacağımızı söyledik. Hatırlarsınız; daha önce "cyberworm" ) şeklinde bir kullanım yapıyorduk yani aradığımız şeyi kendimiz belirliyorduk fakat burada değişken kullandık ve bilgiyi, kullanıcının kendisinden alıyoruz.
Daha sonra bir alta inip yine bir TAB boşluk bıraktıktan sonra eğer aranan kelime bulunduysa 'bulundu' tarzında bir mesaj verdik. Oradaki '$line' ise, ilk satırda tanımladığımız satır sayısını ifade ediyor. O mesaj şu şekilde gözükecektir: "1: '<aranan kelime>' is found.".
case'in sonuna gelirken ' * ) ' şeklinde bir ifade verip geri kalan olasılıkları değerlendiriyoruz. Geri kalan tek bir olasılık var; kelimenin bulunamaması. O yüzden altına inip 'bulunamadı' tarzında bir mesaj veriyoruz ve case'i, 'esac' ile kapatıyoruz.
Bu noktada, while döngüsünü de kapatmamız lazım. Dolayısıyla bildiğiniz üzere 'done' diyoruz ancak dosya aramamız gerekiyor. while döngüsünü anlatırken 'done < deneme.txt' şeklinde bir kullanım yaptık. Ancak burada, kodun başlarında kullanıcıdan aldığımız dosya ismini, değişkenimizi (fileName) yazıyoruz. Elbette, her dosyanın ismi deneme.txt olamaz.
Kodumuzu çalıştıralım ve ne olacağına bakalım.

Çıktıya baktığınızda ilk üç satırda biraz önce sorduğumuz soruları görüyoruz.
Aradığımız şey > cyberworm
Nerede arıyoruz? > Desktop
Dosyanın ismi ne? > deneme.txt
Daha sonra deneme.txt isimli dosyanın içerisinde kaç satır varsa hepsini tarıyor ve bulduğu sonucu bize gösteriyor. En alt satırda bunu görebilirsiniz. Kodumuz gayet güzel çalışıyor ancak ufak bir sorunumuz var.

Çıktı kısmına bakın; normalde satırların 1, 2, 3, 4 ... şeklinde gitmesi gerekmiyor mu? Fakat biz, ilk satırda tanımladığımız line=1 değişkenini hiç arttırmadık ki, nasıl olsun?
Size bir soru: "Bu arttırma işlemini bu kod içerisinde nereye koymalısınız?". Aşağıdaki görsele bakmadan önce bu soruyu düşünün.

Bu işlemi; while'ın içinde, case'in dışında yapmamız lazım. Peki, neden?
while döngüsünü anlatırken işlemlerin, baştan sonra ilerlediğini ve koşul sağlanana kadar bunun tekrarlandığını söyledim. Bu noktada Bash, while döngüsünün içine girdiğinde ilk önce case'e bakıyor ve aradığımız kelimeyi arıyor. İlk seferde bunu bulamadığını düşünelim. Bu durumda Bash, esac üzerinden case'i geçici olarak kapatacak ve tekrar while döngüsünün başına dönecek. İşte tam bu noktada (( line++ )) işlemini, case'in dışına yani esac'ın altına vermemiz lazım ki Bash, case'den çıktığında bu sayıyı artırsın ve başa dönüp işlemleri tekrarlasın. Böyle olduğunda sayı bir artacak ve bir sonraki case ziyaretinde $line değişkeni yeni değerini alacaktır.
Peki, mantığı anladık. Fakat bunu esac'ın bir üstüne yani case'in içerisine yazsak aynı şey olmaz mıydı? Sonuç olarak bir artıp başa dönülecek.

Olmazdı. Çıktı kısmına dikkat edin; 'syntax (sözdizimi) yanlışı. Beklenmeyen token (işaret, simge)'. Girintilere dikkat etmemiz gerektiğini unutmayın. Hatırlayın; biz, case'den sonra bir TAB boşluk veriyorduk. Bunu, case ifadesi esac ile uyuşsun ve case kapansın diye yapıyoruz. Yani case - esac arasına hiçbir şey giremez. Dolayısıyla bu kullanım yanlış olacaktır.
Peki, echo'nun altına koysak?

Bu durumda satır sayısının bir arttırılması işlemi sadece kelimenin bulunamaması durumunda olurdu çünkü orası 'else' yani geri kalan ihtimaller kısmıdır. Böyle bir kullanımda kelime bulunursa, satır sayısı arttırılmayacaktır. Bu yüzden bu teori de çöpe gitmiş oluyor.
Bu uygulamayı daha da geliştirebilirsiniz. En azından denemenizi isterim.
Yayınlanma Tarihi: 2022-09-16 18:23:12
Son Düzenleme Tarihi: 2022-09-23 14:27:31