20
Konuya ait anahtar kelimeler : AWK - Bölüm 2 Awk özel karakterler:
\\Backslash, ters eğik çizgi karakteri.
\a BELL karakteri. ASCII kodu: 7. Uyarı mesajı verme karakteri.
\n Yeni satır karakteri.
\t Yatayda Tab karakteri.
\v Dikeyde satır karakteri.
\" Çift tırnak.
Karakter mantığını daha önceki derslerimizde de anlatmıştık. Yazım kurallarının burada da geçerli olduğunu görüyoruz. Bazı özel karakterler(\, /, ", vb..) print ile yazdırılmak istendiği zaman önlerine ters eğik çizgi alırlar. Şimdi "df" komutunu "-h" parametresi ile kullanarak önce sistemimizdeki dosya sistemlerini görüntüleyelim. "-h" ile daha güzel bir görünüm çıktısı elde ediyoruz, "ls" komutunda olduğu gibi.
[alax@alax script]$ df -h Filesystem Size Used Avail Use% Mounted on dev 2.9G 0 2.9G 0% /dev run 2.9G 636K 2.9G 1% /run /dev/sda1 118G 17G 96G 15% / tmpfs 2.9G 0 2.9G 0% /dev/shm tmpfs 2.9G 0 2.9G 0% /sys/fs/cgroup tmpfs 2.9G 72K 2.9G 1% /tmp /dev/sdb1 299G 168G 131G 57% /run/media/alax/Magara tmpfs 584M 4.0K 584M 1% /run/user/1000 [alax@alax script]$
Şu an sizde yukarıdakine benzer bir çıktı elde etmiş olmalısınız. "df" komutu sistemde bulunan dosya sistemlerinin bağlantı noktaları, boyutları, boş-dolu değer-oranlarını ve mount edilmiş dizin yolunu göstermektedir. Şimdi sistemde bulunan dosya sistemlerinin adları ile kullanım oranlarını yazdıralım. Gördüğünüz üzere toplam değişken sayısı altı(6) dosya sistemi adları "$1" ve dosya sistemi kullanım oranı "$5" değişkeninde tutulacaktır.
[alax@alax script]$ df -h | awk '{print $1 " \t : "$5}' Filesystem : Use% dev : 0% run : 1% /dev/sda1 : 15% tmpfs : 0% tmpfs : 0% tmpfs : 1% /dev/sdb1 : 57% tmpfs : 1% [alax@alax script]$
yukarıdaki gibi bir çıktıyı almış olmalısınız. Awk kullanımında "grep" ve "sed" komutunda olduğu gibi belirli şartlandırmalar kulanabiliriz. Mesela baş harfi "a" olan sütunlar için "/^a/" yada son harfi "z" olan sütunlar için "/.*z$/" gibi. Şimdi yukarıdaki örneğimizi daha özel bir formatta gerçekleştirelim. Mesela sadece eğik çizgi(/) ile başlayan sütunları yazdıralım. Bunun için satır başı anlamına gelen "^" şapka işareti ve "/" eğik çizgi karakterlerini kullanmamız gerekiyor. Eğik çizgi özel bir karakter olduğu için önüne ters eğik çizgi alır.
[alax@alax script]$ df -h | awk '/^\// {print $1 " \t : "$5}' /dev/sda1 : 15% /dev/sdb1 : 57% [alax@alax script]$
"Sed" komutundaki şartlandırmaları "awk" içinde kullanabiliriz, şartlandırmalar aynı mantıkla yorumlanacaktır. Şimdi örneğimiz üzerinde sütunlar içerisinde sonu sayısal ifade ile biten sütunları yazdıralım. "df -h" çıktısı üzerinde bunu sağlayan yalnıza en son satırdır. Dolayısıyla çıktımız en son satırı vermek zorundadır. Örneğimizi uygulayalım.
[alax@alax script]$ df -h | awk '/.*[[:digit:]]$/ {print $1 " \t : "$5}' tmpfs : 1% [alax@alax script]$
BEGIN: Birden fazla awk komutunu kullanacağımız zaman başlangıçta yapılmasını istediğimiz işlemler için "BEGIN" komutu kullanılmaktadır. Yukarıdaki en son örneğimiz için çıktı vermeden önce "Sonu herhangi bir sayı ile biten: " yazısı yazsın ve sonra diğer işlemi gerçekleştirsin istiyorsak "BEGIN" komutunu kullanmalıyız.
[alax@alax script]$ df -h | \ awk 'BEGIN {print "Sonu herhangi bir sayı ile biten:"} /.*[[:digit:]]$/ {print $1 " \t : "$5}' Sonu herhangi bir sayı ile biten: tmpfs : 1% [alax@alax script]$
END: "BEGIN" komutunun zıttı olarak bütün işlemlerden sonra istediğimiz işlemlerin yapılmasını sağlamaktadır. Bunun için komutlardan sonra "END" yazılarak son komut yazılır. Şimdi örneğimizi bu sefer işlem sonunda "Hepsi bu kadar... " yazısının yazılacağı şekilde gerçekleştirelim.
[alax@alax script]$ df -h | \ awk '/.*[[:digit:]]$/ {print $1 " \t : "$5} END {print "Hepsi bu kadar..."}' tmpfs : 1% Hepsi bu kadar... [alax@alax script]$
AWK Ayraçlar: FS: "Field Seperator", Türkçe "Alan ayıracı" anlamına gelmektedir. Şimdiye kadar "awk" uygulamalarımızda sütunları değişkenlere atarken, her kelime arasındaki boşluk yada Tab karakteri baz alındı. $1, $2,$3,...$n değişkenleri için herhangi bir özel ayraç belirtilmediği sürece boşluk,Tab karakteri gözönüne alınacak, ayraç olarak kullanılacaktır. Fakat her zaman sütunlar arasında bu karakterler olmaz. İşte bu gibi durumlarda "FS" parametresi ile yeni bir ayraç tanımlanabilir. Tabi bunu "BEGIN" ile ilk başta yapmamız daha mantıklı olacaktır. Şimdi "awk.txt" adında yeni bir tane dosya oluşturalım ve içerisini aşağıdaki şekilde düzenleyerek kaydedelim.
[alax@alax script]$ > awk.txt [alax@alax script]$ nano awk.txt domates:biber:patlıcan elma:armut:kivi [alax@alax script]$
"awk.txt" dosyamıza bakacak olursak, herhangi bir boşluk,Tab karakter yok. Şimdi normal olarak dosyamızı "awk" ile kullanalım.
[alax@alax script]$ awk '{print $1}' awk.txt domates:biber:patlıcan elma:armut:kivi [alax@alax script]$ awk '{print $2}' awk.txt [alax@alax script]$
Gördüğünüz üzere bütün veriler "$1" değişkenine atandı, diğer bütün değişkenler($2,$3...$n) boş kaldı. Bunun nedeni yukarıda da anlattığımız üzere, varsayılan boşluk,Tab ayracı olmamasıdır. Fakat örneğimizde ayraç olarak kullanabileceğimiz iki nokta ":" karakteri bulunmaktadır, ve bu karakter bütün sütunlarda ortaktır. Şimdi anladığınız üzere bu iki noktayı ayraç olarak belirleyelim ve yukarıdaki örneğimizi tekrardan uygulayalım.
[alax@alax script]$ awk 'BEGIN {FS=":"} {print $1}' awk.txt domates elma [alax@alax script]$ awk 'BEGIN {FS=":"} {print $2}' awk.txt biber armut [alax@alax script]$
OFS: "Output Filed Seperator", Türkçe "Çıktı Alan Ayracı" anlamına gelmektedir. Çıktı olarak yazdırılan verilerin arasındaki ayracı belirlemeye yaramaktadır. Mesela bir önceki dersimizde İsim ve Soyisim ler arasında herhangi bir karakterin olmadığına tanık olduk ve görüntü karmaşık bir halde oluştu. İşte bu noktada "OFS" kullanarak yazıdırılan sütunların arasında istediğimiz ayracı kullanabiliriz. Bunun için hangi değişkenler arasında "OFS" kullanılmasını istiyorsak o değişkenleri virgül ile ayırmalıyız. Mesela "$1" ve "$3" değişkenlerinin aralarında belirli bir "OFS" olarak yazılmasını istiyorsak "print" komutundan sonra "$1,$3" şeklinde yazmalıyız. Şimdi bir önceki dersimizde oluşturduğumuz "awkex" dosyamızda bunları uygulayalım. Örneğimizde "FS" belirtmeye gerek yok zaten varsayılan olarak boşluk,Tab karakteri bulunmakta. Bu yüzden sadece "OFS" belirtmemiz yetecektir.
[alax@alax script]$ awk 'BEGIN {OFS="---"} {print $1,$2}' awkex İsim---Soyisim Ahmet---Budak Asuman---Budak Ali---Cangöz Aslı---Cangöz [alax@alax script]$
ORS: "Output Record Seperator" Türkçe "Kayıt Çıktısı Ayracı", yani satırlar arasındaki ayraç olarak anlaşılabilir. Her bir satırdan sonra belirlenen karakter/kelime/kelime grubunun yazdırılmasını sağlamaktadır. Tabi "ORS" ayracı başında ve sonunda "yeni satır(\n)" karakteri ile kullanılmalıdır. Yukarıdaki örneğe "ORS" ayracı tanımınıda ekleyelim. Ayraç tanımları arasında noktalı virgül ";" kullanılır.
[alax@alax script]$ awk 'BEGIN {OFS="---" ; ORS="\n--->\n"} {print $1,$2}' awkex İsim---Soyisim ---> Ahmet---Budak ---> Asuman---Budak ---> Ali---Cangöz ---> Aslı---Cangöz ---> [alax@alax script]$
NR: "Number Records" Türkçe "Kayıt Numaraları" anlamına gelmektedir. Biz şu ana kadar kayıtları belirli "OFS" ve "ORS" ayraçları ile ekrana yazdırıyoruz, peki kayıtların sırasını yada numarasını da öğrenmek istersek? O zaman "NR" komutunu kullanmamız gerekecektir. "NR" komutu her kayıt yada satır için numarasını barındırmaktadır. Yukarıdaki örneğimizi "NR" ile tekrar uygulayalım.
[alax@alax script]$ awk 'BEGIN {OFS="---" ; ORS="\n--->\n"} \ {print NR "\t" $1,$2}' awkex 1 İsim---Soyisim ---> 2 Ahmet---Budak ---> 3 Asuman---Budak ---> 4 Ali---Cangöz ---> 5 Aslı---Cangöz ---> [alax@alax script]$
"NR" yi nerede kullanırsanız orada kayıt numarasını yazacaktır. AWK Script Dosyası: Birden fazla "awk" komutunu bir script dosyasına yazıp kaydettikten sonra "-f" opsiyonu ile bu script dosyasını çağırıp, komutlarınızın istediğiniz dosya üzerinde otomatik olarak işletilmesini sağlayabilirsiniz. Şimdi yukarıdaki örneklerimizi bir script dosyası içerisinde yazıp kullanmaya çalışalım. Bunun için bir adet "komut.awk" adında bir "awkscript dosyası" oluşturalım ve içeriğini aşağdaki şekilde düzenleyip kaydedelim. Örneğimizi "awk.txt" dosyası için uygulayacağız, o yüzden "FS" tanımlaması yapmamız da gerekmektedir.
[alax@alax script]$ > komut.awk [alax@alax script]$ nano komut.awk BEGIN {FS=":" ; OFS="-" ; ORS="\n-->\n"} { print "Kayıt numarası " NR ":\t" $1,$3} END {print "Toplam kayıt sayısı: " NR} [alax@alax script]$
Evet şimdi son örneğimizi yapalım ve "komut.awk" scriptini "awk.txt" dosyası için uygularak sonucunu görelim.
[alax@alax script]$ awk -f komut.awk awk.txt Kayıt numarası 1: domates-patlıcak --> Kayıt numarası 2: elma-kivi --> Toplam kayıt sayısı: 2 --> [alax@alax script]$
İnternette arama yaparak daha fazla "AWK" örneğine ulaşabilirsiniz. Lütfen pratik yapmayı unutmayınız.