12/03/2004 Adana, v.0.1b
|
Tipik awk programlarında bütün girdiler ya standart girişten (öntanımlı olarak bu klavyedir, fakat boru işareti ile başka bir komuttan da olabilir ) ya da komut satırından belirtilen bir dosyadan alınır. Eğer girdi dosyası belirtmişseniz, awk onları düzenli bir şekilde okur, önce birinci veriden başlayarak sonuna kadar bütün verileri işler. O an belirtilmiş olan dosya ismi FILENAME isimli sabitte tutulur. Girdi kayıt olarak okunur. Programınızdaki kurallara göre bir anda bir kayıt işlenir. Öntanımlı olarak herbir kayıt bir satırdır. Her kayıt otomatik olarak alanlara ayrılır. Bu işlem, kayıt parçaları üzerinde çalışan programlar için oldukça uygun bir ortam sağlar. Nadir rastlanan durumlarda ise "getline" komutunun kullanımına ihtiyaç duyabilirsiniz. "getline" komutu çok değerlidir, hem birkaç dosyadan kesin girdi alabilme imkanı sağlar hem de komut satırından belirtilen dosya ismini kullanabilir. |
| 7.i Alanlar Kayıtlar İçinde Nasıl Ayrılır awk, programınız için, kayıtlar ve alanlar şeklinde girdiyi böler. awk, o anki girdi dosyasından okurken kayıtların numaralarını tutar. Bu değer FNR sabitinde saklanır. Yeni dosya okunurken bu değer sıfırlanır. Bir diğer sabitte NR'dir. NR, bütün veri dosyalarından okunan girdi kayıtlarının toplam sayılarını tutar. NR sıfır ile başlar fakat asla otomatik olarak sıfırlanmaz. Kayıtların birbirinden bazı karakterlerle ayrılırlar. Öntanımlı olarak kayıt ayıracı yenisatır karakteridir. Böylelikle öntanımlı olarak kayıtlar tek satır olarak alınır. RS sabitine atayarak, farklı karakterleri kayıt ayırma karakteri olarak kullanabiliriz. Diğer sabitler gibi RS sabitine de değer atamak için '=' operatörünü kullanırız. Yeni kayıt ayıracı karakter, çift tırnak karakterleri arasında yazılmış bir katar halinde belirtilir. Bu atama işlemi genellikle uygulamanın başında girdi işlenmeden önce yapılır, bu suretle ilk kayıt uygun ayıraç ile okunur. Bu işlem özel BEGIN kalıbı kullanılarak yapılır. Örneğin:
awk 'BEGIN { RS = "/" }
{ print $0 }' telefon_listesi
girdiden kayıt okunmadan önce RS sabiti "/" değeri ile değiştirildi. Bu, bölü karakteri ile başlayan katarı belirtir; kayıtlar bölü karakterleri ile ayrılmış olurlar. Sonra girdi dosyası okunurken, awk programındaki ikinci kural (kalıpta yer almayan işlem) herbir kayıt için ekrana dökülür. Herbir print ifadesinde çıktının sonuna yenisatır karakteri eklenir, yani her kayıtta bölü karakteri yerine yenisatır karakteri yazılır. Aşağıda, telefon_listesi veri dosyası bu programda girdi olarak kullanılmıştır: |
]# awk 'BEGIN { RS = "/" }
> { print $0 }' telefon_listesi
-| isim tarih saniye A:gündüz, B:gece, C:hafta sonu
-|
-| ali 2003
-| 08
-| 18 300 A
-| okan 2003
-| 08
-| 19 1200 B
-| murat 2003
-| 08
-| 21 650 A
-| kemal 2003
-| 07
-| 20 100 A
-| recep 2003
-| 08
-| 02 230 C
-| sami 2003
-| 09
-| 01 400 C
-| halil 2003
-| 08
-| 05 450 B
|
|
Aşağıda telefon_listesi isimli veri dosyasının orjinal haldeki çıktısı yer almaktadır: |
]# awk '{ print $0 }' telefon_listesi
-| isim tarih saniye A:gündüz, B:gece, C:hafta sonu
-|
-| ali 2003/08/18 300 A
-| okan 2003/08/19 1200 B
-| murat 2003/08/21 650 A
-| kemal 2003/07/20 100 A
-| recep 2003/08/02 230 C
-| sami 2003/09/01 400 C
-| halil 2003/08/05 450 B
|
|
RS sabitinin değerini değiştirmek için bir diğer yolda komut satırından atama yapmaktır. Bu şekilde de aynı sonuç ortaya çıkacaktır. Kullanımı aşağıdaki gibidir:
awk '{ print $0 }' RS="/" telefon_listesi
RS sabitine telefon_listesi işlenmeden önce değer atanacaktır. RS sabitine atanan boş katar ("") özel bir anlam taşır. Bir veya birden çok boş satır ile ayırılan kayıtlarda kullanılır. Daha fazla ayrıntı için Çok Satırlı Kayıtlara bakınız. Eğer RS sabitinin değerini awk programının çalışmasının ortasında değiştirirseniz, yeni değer sonra gelen kayıtlar için sınırı belirler. Fakat kayıt hala, önceki işlendiği gibi işlenecektir ve değişiklikten etkilenmeyecektir Kayıdın sonundan sonra kesin olan, girdi içinde eşleştirilen RS değerini gawk RT değişkenine atar. gawk kullanıldığında, RS'nin değeri bir-karakter katarı ile sınırlandırılmaz. O bazı regexp ifadeleri olabilir. Genel olarak, herbir kaydın sonundan sonraki katar regexp ile eşleştirilir; sonraki kayıt eşleştirilen katardan sonra başlar. Bu genel kural gerçekte genel durumda çalışır, RS nerde kapsanıyorsa yenisatır gibi: kayıt sonraki eşleştirilen katarın başında son bulur (girdideki sonraki yeni satır) ve sonraki kayıt katarın sonundan sonra başlar (sonraki satırın ilk karakterinde). Yeni satır hiçbir kaydın parçası değildir, çünkü RS ile eşleştirilen katarlarla sınırlandırılır. RS tek karakter olduğunda, RT aynı tek karakteri içerir. Bununla birlikte, RS bir regexp ise, RT girdideki, regexple eşleştirilen katarı içerir. Aşağıdaki örnek kullanım şeklini izah etmektedir. RS'ye bir regexp atanmıştır. Bu regexp yenisatır ve bir veya birden çok büyük harfli kelime serilerinin her ikisini de isteğe bağlı başlatıcı ve/veya devam ettirici boşluk ile eşleştirir: |
]# echo kayıt 1 AAAA kayıt 2 BBBB kayıt 3 |
> gawk 'BEGIN { RS = "\n|( *[[:upper:]]+ *)" }
> { print "Kayıt =", $0, "ve RT =", RT }'
-| Kayıt = kayıt 1 ve RT = AAAA
-| Kayıt = kayıt 2 ve RT = BBBB
-| Kayıt = kayıt 3 ve RT =
-|
|
|
Çıktıdaki son satır fazladan boş bir satırdır. Bunun nedeni RT'nin değerinin yenisatır olmasıdır ve print ifadesi o sonlandırılan yeni satırı sağlar. Eğer RS sabitine uygun bir regexp atadıysanız örneğin RS = "abc(XYZ)?" gibi bir ifadenin iki kaydı ayırmasını sağlayabilirsiniz. RS'nin regexp olarak kullanımı ve RT değişkeni gawk'ye özeldir. Bunlar compatibility modda bulunmazlar. Compatibility modda kaydın sonunu belirlemek için RS'nin yalnız birinci karakteri kullanılır. Not: RS = "\0" taşınamaz. Veri dosyasının içindeki veriyi tek kayıt gibi gösterebilirsiniz. Bunu yapmak için tek yol girdi dosyasında bulunmayan bir değeri RS sabitine atamaktır. Genel yol içinde bunu yapması zordur, öylesine girdi dosyaları için o program her zaman çalışır. Bu durumda, bütün bitleri sıfıra eşit olan karakterden ibaret olan NULL karakter'i yazı dosyaları için düşünmelisiniz. Bu durumda aşağıdaki kullanımdaki değer, RS'ye atanabilecek iyi bir değerdir:
BEGIN { RS = "\0" } # bütün dosya sadece bir kayıttır?
gawk bunu kabul eder ve kayıt ayıracı olarak NULL karakteri kullanır. Bununla birlikte bu kullanım diğer awk yorumlayıcıları için taşınabilir değildir. Bütün diğer awk yorumlayıcıları, katarları C-stili katarlar gibi depolarlar. C katarları NULL karakteri katar sonlandırıcı olarak kullanırlar. Bunun için RS = "\0" ifadesi ile RS = "" ifadesi aynı anlamdadır. Bütün dosyanın içeriğini ekrana dökmek için yapılacak en iyi yol, kayıtları teker teker alıp sıra ile hepsini ekrana basmaktır. |
| 7.ii Alanları Gözden Geçirme awk girdi kaydını okuduğunda, kayıt otomatik olarak alan yığını içinde yorumlayıcı tarafından yorumlanır ve ayrıştırılır. Öntanımlı olarak alanlar boşluk karakteri ile ayrılmıştır (bir cümledeki kelimeler gibi). awd'de bir veya birden çok boşluk, tab veya yenisatır, boşluk anlamına gelir. formfeed, diket tab, vs. gibi diğer karakterler, diğer diller için boşluk gibi düşünülebilir ama awk için değildir. Alanlara ayırmanın amacı, verileri alarak işlemeye müsait hale getirmektir. Bu şekilde alanları ayırmanız sizin verilere daha hakim olmanızı sağlayacakır. awk programlarında dolar-işareti ($) alanları ifade etmek için kulanılır. Dolar işareti sağındaki sayıyla birlikte alanları temsil eder. Mesela, $1 birinci, $2 ikinci ve diğerleri aynı şekilde diğer alanlardaki verileri tutarlar. Örneğin aşağıdaki girdi satırını alalım: Bu örnek oldukça yarayışlı olacak hoş bir örnektir. Burdaki birinci alan veya $1 "Bu", ikinci alan veya $2 "örnek" ve diğerleri de aynı şekilde değer alırlar. Son alan ise sekizinci veya $8 alanıdır ve değeri de "örnektir.". Çünkü orda 'r' ile '.' arasında boşluk karakteri yoktur ve nokta karakteri de sekizinci alana dahil sayılır. NF sabiti o anki işlenen kayıtta bulunan alan sayısını tutar. awk, her kayıt okunduğunda NF değerini otomatik olarak yeniler. Ne kadar alan olduğu önemli olmaksızın $NF ifadesi her kaydın son alanının taşıdığı verinin değerini içerir. Yukarıdaki örnek için $NF ifadesi $7 ifadesi ile aynı değeri taşır. Kayıttaki alan sayısından fazla bir sayı (yani yukarıdaki örnek için $9, $10, ... ifadeleri) boş katar içerir (eğer sayısal bir işlem için kullanırsanız sıfır değerini verir). $0 ifadesi ise gördüğünüz gibi sıfırıncı alanı gösterir ve bu özel bir durumdur. Bu ifade kendine özgü alanlarda, hiçbir şekilde bir değişiklik yapmadığınızda tüm girdi kaydını gösterir. Aşağıdaki örnekteki gibi: |
]# awk '$2 ~ /08/ { print $0 }' telefon_listesi
-| ali 2003/08/18 300 A
-| okan 2003/08/19 1200 B
-| murat 2003/08/21 650 A
-| recep 2003/08/02 230 C
-| halil 2003/08/05 450 B
|
|
Bu örnek telefon_listesi isimli veri dosyasında $2 ifadesinin belirttiği ikinci alana bakar ve '08' katarını içeren kayıtları ekrana basar. ~ operatörü eşleştirme işlemini yapmak için kullanılmıştır (bu operatör hakkında daha geniş bilgi için regexp bölümüne bakınız). Aradaki farkı görmek için aşağıdaki örneğe bir bakınız: |
]# awk '/08/ { print $2, $NF }' telefon_listesi
-| 2003/08/18 A
-| 2003/08/19 B
-| 2003/08/21 A
-| 2003/08/02 C
-| 2003/08/05 B
|
|
Bu örnekte ise girilen kayıt içinde '08' katarına bakılır ve her eşleştirilen girdi kaydı için ikinci alan ve o kaydın son alanı ekrana basılır. |
| 7.iii Değişen Alan Numaraları Alan numaralarının sabit olmaları gerekmemektedir. Bazı ifadelerde $'dan sonra alanı belirten başka bir ifade kullanılabilir. İfadenin değeri alan numarasını belirtmelidir. Eğer değeri sayı katarı ise sayıya dönüştürülür. Örneğin:
awk '{ print $NR }'
Sırayla her kaydın numarasını tutan NR sabiti her çağrılışında $ ile belirtildiğinden her kayıtta o kaydın numarasındaki alanın değerini alır. Yani birinci kayıtta $1, ikinci kayıtta $2, ve diğerleride aynı şekilde ifade edilmiş olur. Eğer alan sayısı kayıt sayısından az olursa o zaman alan sayısından fazla değerlerde boş satır ekrana basılacaktır. Aşağıdaki örnekte ise alan numarası gösterecek şekilde daha farklı bir ifade kullanılmıştır.
awk '{ print $(2*2) }' telefon_listesi
awk ifadeyi (2*2) işler ve sonuç değerini alarak alan numarası olarak kullanır. * işareti matematiksel çarpma işareti olarak kullanılmıştır ve 2*2 ifadesi 4 olarak hesaplanır. Parantez kullanılmasının nedeni çarpma işleminin sonucunun $ işaretinden sonra yer almasını sağlamak içindir. Eğer parantez kullanılmasaydı o zaman da ikinci alandaki verinin değeri (o değer sayısal bir değeri ifade eden bir katar ise sayıya çevrilecek, değilse sıfır değerini alacaktır) ile 2 sayısının çarpımının sonucu ekrana basılacaktı. Eğer sonucu sıfır olacak bir matematiksel ifadeyi kullanacak olursak o zaman kaydın tümünü yani $0'ı elde etmiş olacağız. Negatif alan numaralarına izin verilmez ve böyle bir durumda program sonlandırılır. (POSIX standartlarına göre negatif alan numarası tanımlandığında ne yapılacağı belirtilmemiştir. gawk bu durumda programı sonlandırır. Diğer awk yorumlayıcıları ise daha farklı davranabilirler.) Önceki bölümde belirtildiği gibi awk, o anki alan numarasını NF sabitinde tutar. $NF ifadesi ise özel bir şekil değildir ve NF'nin değeri direk alan numarası olarak kullanılır. |
| 7.iv Alanın İçeriğini Değiştirme Alanın içeriğine awk ile bakılabilir ve içerik istenildiği gibi değiştirilebilir. (Gerçek girdiye dokunulmaz; awk asla girdi dosyasının yapısını değiştirmez. Sadece programa alınan veriler değiştirilir.) Aşağıdaki örneğe bir göz atalım: |
]# awk '{ eski_alan = $3 ; $3 = $3 - 10; print eski_alan, $3 }' ay_listesi
-| 400 390
-| 425 415
-| 375 365
-| 350 340
...
|
|
Program ilk önce üçüncü alanın içeriğini eski_alan değişkeninde saklar. - işareti matematiksel çıkarma operatörü olarak kullanılmıştır. "$3 - 10" ifadesi ile üçüncü alandaki verinin değerinden 10 çıkarılıl ve "$3 = $3 - 10" ifadesiylede üçüncü alana tekrar atanır. Daha sonra üçüncü alanın eski değeri ve yeni değeri ekrana basılır. Bu iş için $3 alanındaki yazı, sayı olarak düşünülmelidir; o yazı karakteri bilgisayarın aritmetik işlemleri yapabilmesi için sayıya çevrilmelidir. Çıkarma işleminden sonra ise üçüncü alana atanan değer tekrar katara çevrilmelidir. Bunlar otomatik olarak awk tarafından yapılır. Alanın değeri değiştiğinde, kayıttaki yazı, eskisinin yerine yeni alanı içerecek şekilde tekrar hesaplanır. Diğer kelimeler içinde, $0 da kaldırılan alanın gösterimi değiştirilir. Bunu için, bu program girdi dosyasının kopyasını ekrana basar (çıkarma işlemi yapılmış şekilde): |
]# awk '{ $3 = $3 - 10; print $0 }' ay_listesi
-| ocak 21 390 1
-| subat 21 415 2
-| mart 11 365 2
-| nisan 21 340 2
...
|
|
Elimizdeki alanlar dışında yeni bir alan daha tanımlayıp kullanmamız mümkündür. Örneğin: |
]# awk '{ $5 = ($4 + $3 + $2); print $5 }' ay_listesi
-| 422
-| 448
-| 388
-| 373
...
|
|
Biz sadece $5 diye yeni bir alan oluşturduk ve $2, $3, $4 alanlarının değerlerinin toplamlarını bu alana atadık. Yeni alan oluşturulunca $0'ın değeri yeni alanda eklenmiş şekilde yine değişir. Eğer $0 değişkenini ekrana bastıracak olursak yeni eklediğimiz $5 alanınında eklenmiş (yani beş tane alan oluyor) olduğunu görürüz. Bu yeniden hesaplama NF sabitinide değiştirir. NF'nin değeri oluşturduğumuz en yüksek alan numarasını alır. $0'in tam formatı, nasıl değiştiği henüz görmediğimiz OFS (Output(çıktı) Field(alan) Separator(ayıracı)) sabitiyle ilgilidir. Bununla birlikte sadece alanlar dışında yeni bir alan tanımladıysak $0 ve NF'nin değerleri değişmez. Bu yeni alan sadece boş katar gösterir. Örneğin: if ($(NF+1) != "") print "olmadı!" else print "herşey normal" "herşey normal" katarı ekrana basılacaktır, çünkü NF+1 şüphesizki alanların dışında bir değerdir. Önemli bir nokta var olan bir alanı değiştirdiğimizde $0'ın değişiyor olması fakat NF'nin değişmiyor olmasıdır. Hatta boş alan atasak bile. Örneğin: |
]# echo a b c d | awk '{ OFS = ":"; $2 = ""; print $0; print NF }'
-| a::c:d
-| 4
|
|
Alan ordadır, yani a ile c arasındaki iki noktaların arasındadır fakat boşluk değerine sahiptir. Peki yeni bir alan oluşturursak bu örneğin çıktısı ne olur: |
]# echo a b c d | awk '{ OFS = ":"; $2 = ""; $6 = "yeni"; print $0; print NF }'
-| a::c:d::yeni
-| 6
|
|
Arada kalan alan, yani $5 alanı boş değerle oluşturulur ve NF altı değerini alarak yenilenir. Eğer NF'nin değerini azaltacak olursak o zaman $0'ın değeri NF'nin yeni değerine göre yeniden hesaplanır. Aşağıdaki örneğe dikkat edin: |
]# echo a b c d e f | awk '{ print "NF =", NF; NF = 3; print $0 }'
-| NF = 6
-| a b c
|
|
Önemli: Bazı awk sürümlerinde NF azaltıldığında $0 yeniden hesaplanmaz. Dikkatinize sunulur. Son olarak, o anki değeri ve OFS'yi kullanarak girdi kaydını yeniden yapılandırmak güçlü awk'de mümkündür. Bunu yapmak görünüşte zararsız bir kullanımdır: $1 = $1 # yeniden yapılandırmada güçlü kayıt print $0 # veya $0 ile değilse hepsi Bu güçlü awk kaydı yeniden yapılandırır. Görüldüğü gibi açıklama ekleyerek yardım da sağlanabilir. $0 ile alanlar arasında bir yakınlık oranın ayrı tarafıdır. $0'a herhangi bir atama FS'nin o anki değeri kullanılarak alanlar içinde yeniden bir incelemeye sebep olur. Böyle bir değişiklik olsa bile sub ve gsub gibi $0'ı güncelleyecek fonksiyonlar vardır. |
| 7.v Alanların Nasıl Ayrılacaklarının Belirtilmesi Alan ayıracı tek karakter veya regexp olabilir. awk girdi kaydındaki karakterleri sırasıyla, ayıraçla eşleştirme yapılana kadar tarar. Eşleştirilen iki ayıraç arasındaki karakterlerin bütününü bir alan olarak alır. Aşağıdaki örnekte '*' karakterini boşluğu belirtmek için kullandık. Alan ayıracının 'oo' ifadesi olduğunu varsayarsak: moo goo gai pan ayrılan üç alan şöyledir: m, *g ve *gai*pan. Alan ayıracı FS ile belirlenir. Kabuk programcılarına not: awk IFS'yi kullanmaz, o POSIX-uyumlu kabuklarla kullanılır (Unix Bourne shell, sh, veya bash gibi). FS'nin değeri '=' atama operatörüyle değiştirilebilir. Genelde girdi kaydı alınıp uygulama başlamadan önce kayıtları en uygun şekilde okuyabilmek için en uygun ayıraç atanır. Bunu BEGIN kalıbı içerisinde yapabilirsiniz. Örneğin, burda FS'ye ',' karakteri atanmıştır:
awk 'BEGIN { FS = "," } ; { print $2 }'
Verilen girdi satırı: Okan ÖZEREN, 29 Çiçek Sok., Seyhan, PK 01120 Bu programın çıktısı "*29*Çiçek*Sok." olacaktır Bazen girdi verisi alan ayıracını içerir. O zaman alanları ayırmak için başka bir yol düşünmek gerekir. Örneğin, kişi isminde virgülle ayrılmış bir açıklama yer alıyor olsun: Okan ÖZEREN, 1981, 29 Çiçek Sok., Seyhan, PK 01120 Aynı program "*29*Çiçek*Sok." yerine "*1981"'i ekrana basar. Eğer alan ayıracınızı ve veri düzenini uygun bir şekilde ayarlarsanız bu sorunu çözmeniz mümkündür. Alanlar normalde boşluk ile ayrılırlar (boşluklar, tab veya yenisatır), ama tek boşluk ile değil. Satırdaki iki boşluk boş bir alanı sınırlandırır. Eğer FS, mesela ',' gibi herhangi bir tek karakter ise, her ortaya çıkışında iki alanı ayırır. İki kere ard arda ortaya çıkışında ise boş bir alanı sınırlandırıyor demektir. Eğer satırın başında veya sonunda yer alıyorsa yine boş bir alanı sınırlandırıyor demektir. Boşluk karakteride tek karakterdir fakat bu kurallara uymaz. |
| 7.v.1 Alanları Ayırırken Regexp Kullanımı Bir önceki bölümde, tek karakter veya basit katarların alan ayıracı olarak kullanılabileceğini gördük. Genellikle FS sabitinin değeri bazı regexpleri kapsayan katarlar olmalıdır. Bu durumda, regexp alan ayıracı için farklı farklı eşleştirmeler olacaktır. Örneğin şu atama: FS = ", \t" girdi satırında virgül daha sonra tek boşluk daha sonra tab karakteri olan her alan eşleştirmeye uyar. FS'e "[ ]" (sol köşeli parantez, boşluk, sağ köşeli parantez) atanabilir. Bu regexp tek boşlukla eşleştirilir ve hiçbirşey yoksa. FS = " " ve FS = "[ \t\n]+" (bu regexp bir veya daha çok boşluk, tab veya yenisatır ile eşleştirilir) arasında önemli bir fark vardır. FS'nin her iki değeri için, alanlar ardarda bitişik boşluklar, tablar ve/veya yenisatırlar arasındadır. Bununla birlikte, FS'in değeri " " olduğunda, awk kayıttan ilk boşluğu atar. Örneğin, aşağıda boru işareti ile alınan veride b ekrana basılır: |
]# echo ' a b c d ' | awk '{ print $2 }'
-| b
|
|
Bunun yanında, boru işareti ile (her kelime etrafında ekstradan boşluk olursa): |
]# echo ' a b c d ' | awk 'BEGIN { FS = "[ \t\n]+" } { print $2 }'
-| b
|
|
Bu durumda ilk alan null veya boş olacaktır. Kayıt başlarındaki boşluk, $0 yeniden hesaplanırsa silinir. Örnekteki gibi: |
]# echo ' a b c d' | awk '{ print; $2 = $2; print }'
-| a b c d
-| a b c d
|
|
İlk print ifadesinde kayıt okunduğu gibi, başındaki boşlukla ekrana basılır. $2'nin kendine atanması, sırayla $1'den $NF'ye kadar OFS'nin değeri ile ayrılmış bir şekilde $0'ı tekrar yapılandırır. Çünkü $1 bulunduğunda başlangıç boşluğu yok sayılır ve $0'ın parçası değildir artık. Son olarak son print ifadesi yeni $0'ı ekrana basar. |
| 7.v.2 Her Karakteri Ayrılmış Alan Yapma Kayıttaki her karakteri ayrılmış birer alan olarak almak istediğimiz zaman bu kullanım şeklini uygulayabiliriz. gawk'da bu işlem FS'e null katar ("") atamakla yapılabilir. Bu durumda kayıttaki her ayrı karakter ayrılmış birer alan olarak algılanacaktır. Örneğin: |
]# echo " a b" | gawk 'BEGIN { FS = "" }
> {
> for (i = 1; i <= NF; i = i + 1)
> print "Alan", i, " değeri ", $i
> }'
-| Alan 1 değeri
-| Alan 2 değeri a
-| Alan 3 değeri
-| Alan 4 değeri b
|
|
Geleneksel (Traditional) durumda, "" ifadesi FS'ye atanamaz. Bu durumda UNIX awk'de girilen kayıttan yalnız bir alan alınır. Uygun (Compatibility) modda ise eğer FS null katar ise o zaman gawk bile böyle davranır. |
| 7.v.3 FS Sabitine Komut Satırından Değer Atama FS'ye komut satırından değer atanabilir. -F parametresini kullanarak bu işlemi yerine getirebiliriz. Örneğin: awk -F, 'program' girdi_dosyaları FS sabitine ',' karakteri atanmıştır. -F ile -f parametrelerinin anlamları farklıdır. -f parametresi programa kod dosyası dahil etmek için kullanılır. -F ve -f fonksiyonlarının her ikisinide aynı komut içinde kullanabilirsiniz. -F ile komut satırından değer kullanmak ile FS sabitine değer atamak aynı anlama gelir. Alan ayıracı içindeki bazı özel karakterleri en uygun şekilde kaçırmak gerekir. Örneğin, '\' karakterini komut satırından, alan ayıracı olarak atamak istediğinizde kullanım şekli şöyledir: FS = "\\" ifadesiyle awk -F\\\\ '...' dosyalar ... ifadesi aynı anlama gelir Çünkü \ karakterini kabukta kullanabilmek için awk'de -F\\ şeklinde bir yazım şekli gerekir. O zaman awk \\ ifadesini işler ve sonuçta \ karakterini alan ayıracı olarak geri verir. Özel bir durumda, compatibility modda, eğer -F parametresi ile t karakteri alınırsa, o zaman FS sabitinin değeri TAB karakteri olacaktır. Eğer, kabukta tırnak işareti olmadan -F\t şeklinde kullanırsanız \ karakteri silinir, fakat awk yinede sizin istediğiniz gibi alan ayıracı olarak TAB karakterini alacaktır ve t karakterini almayacaktır. Gerçektende t karakterini alan ayıracı olarak kullanmak istiyorsanız, o zaman -v FS="t" veya komut satırında -F"[t]" ifadelerini kullanmalısınız. Örneğin, ornek.awk awk program dosyasını çağıran, /250/ kalıbı ile print $1 işlemini yapan kodu kullanalım: ornek.awk
/50/ { print $1 }
FS'yi / karakteri ile yükleyip programı telefon_listesi isimli veri dosyamızla çalıştıralım. Aşağıdaki komut, 50 katarı geçen satırların / ayıracına göre ilk alanlarını ekrana basar. |
]# awk -F/ -f ornek.awk telefon_listesi -| murat 2003 -| halil 2003 |
|
Unix sistem parola dosyasını işlediğinizde muhtemelen alan ayıracı olarak tek karakter kullanıldığını göreceksiniz. Bazı Unix sistemlerinde her kullanıcının bilgileri herbiri için ayrı bir satırda yer almaktadır. Ve bu satırlardaki bilgiler ise iki-nokta (:) ile ayrılır. İlk alan kulanıcı adı ve ikinci alan kullanıcı parolasıdır (tabiki şifrelenmiş veya gölgelenmiş hali). passwd dosyası aşağıdaki yapıdadır: seeyou:x:501:501:Okan ÖZEREN:/home/seeyou:/bin/bash Aşağıdaki program passwd dosyası içinde parolası olmayan kullanıcıları arar: awk -F: '$2 == ""' /etc/passwd |
| 7.v.4 Kısaca Alanların Ayrılması FS'e değer olarak katar sabitlerini atadığınızda nelerin nasıl olduğunu bilmeniz çok önemlidir. Örneğin, Unix awk ve gawk'de FS = "\.." ifadesiyle aslında FS'e ".." katarını atamış olursunuz (tersbölü karakteri çıkarılır). Bu oluşturulan regexp ifade "alanlar bu katara her rastlanışında birbirinden ayrılırlar" anlamına gelir. Eğer onun yerine "\.." ifadesini ayıraç yapmak istiyorsanız o zaman FS = "\\.." atamasını yapmanız gerekmektedir. Aşağıdaki tablo, alanların, FS sabitine atanan değerle nasıl ayrıldığını gösterir (== ifadesi "eşit ise" anlamına gelir):
Önemli Not: FS'i Değiştirmek Alanları Etkilemiyorsa POSIX standartlarına göre awk, okuma sırasında her kaydı alanlara ayrılmış gibi farzeder. Özel bir durumda bu düşünce, eğer siz kayıtların okunmasından sonra FS'yi değiştirirseniz, o zaman alanların değeri (alanların nasıl ayrılacağı gibi) yenisine göre değilde eski FS'ye göre belirlenecektir. Bununla birlikte awk'nin bazı sürümlerinde bu şekilde çalışmaz. Onun yerine alanlar gerçek haliyle gösterilene kadar ayrılmalarını ertelerler. Alanlar FS'nin o anki değeri ile ayrılırlar. Bu davranış alanların olduğundan farklı alınmasına neden olur. Aşağıdaki örnek iki metod arasındaki farkları tasvir etmektedir:
sed 1q /etc/passwd | awk '{ FS = ":" ; print $1 }'
hangi metod olursa olsun genellikle aşağıdaki çıktı alınır: root awk'nin hatalı bir sürümünde, gawk'de şunun gibi bir çıktı alınır: root:nSijPlPhZZwgE:0:0:Root:/: Önemli Not: FS ve IGNORECASE (gawk'nin eski versiyonlarında) IGNORECASE değişkeni, FS yalnız regexp bir ifade aldığında alan ayırmada etkilidir. FS tek bir karakter aldığında veya bir kelime alsa bile etkili değildir. Aşağıdaki koda bir göz atın: |
]# awk 'BEGIN{ FS = "c" ;
> IGNORECASE = 1;
> $0 = "aCa";
> print $1; }'
-| aCa
|
|
Çıktı "aCa" olmuştur. Eğer gerçekten alfabedeki karakterlerin büyük küçük harf ayrımına göre ayırma yapmak istiyorsanız regexp bir ifade kullanmalısınız. Örneğin FS = "[c]". Bu durumda IGNORECASE etkili olacaktır. |
]# awk 'BEGIN{ FS = "[c]" ;
> IGNORECASE = 1;
> $0 = "aCa";
> print $1; }'
-| a
|
|
|
| 7.vi Sabit Uzunluklu Verileri Okuma Not: Bu bölüm gawk'de biraz daha uzmanlık gerektirir. Eğer yeni bir awk kullanıcısı iseniz dökümanı baştan itibaren okumanızı tavsiye ederim. gawk 2.13 daha kolaylık sağlaması açısından bu özelliği sunmuştur. Bu özelliğe göre alanlar, alan ayıraçlarıyla ayrılmak yerine uzunluğu belirli bir bölgede bulunmaktadırlar. Örneğin, girdideki verilerin bu doğal yerleşimi, eski Fortran programlarında nerdeki sayıların birlikte çalışacaklarından veya programların çıktılarının önceden belirlendiği gibi diğer programlara girdi olarak verilmesi fikrinden çıkmıştır. Son örnektekine göre bütün sütunlar bir tabloya göre belirli bir sayısal değerle sabitlenerek ve boş alanlarda boş bırakılarak belirlenir. Tabiki FS ile normal alan ayırma bu durumda geçersiz olacaktır. Gerçi taşınabilir awk progragramları $0 üzerinde "substr" serilerini kullanırlar. Bu kullanım alanların yüksek sayıda değerleri için etkisiz ve hantaldır. Girdi kayıtlarındaki sabit uzunluklu verilerin nasıl ayrılacağı, FIELDWIDTHS sabitine belirli bir alan uzunluk tablosu atamakla belirlenir. Her sayı bir sütunun uzunluğunu belirtir. Eğer alanlar arasındaki sütunları yoksaymak istiyorsanız, belirttiğiniz uzunluğu sonradan çıkarabilirsiniz. Alan uzunluğunun pozitif olmaması ölümcül hataya neden olur. Aşağıdaki veriler Unix w aracının bir çıktısıdır. Bu veriler FIELDWIDTHS'in kullanımı için oldukça uygundur: 10:06pm up 21 days, 14:04, 23 users User tty login idle JCPU PCPU what hzuo ttyV0 8:58pm 9 5 vi p24.tex hzang ttyV3 6:37pm 50 -csh eklye ttyV5 9:53pm 7 1 em thes.tex dportein ttyV6 8:17pm 1:47 -csh gierd ttyD3 10:00pm 1 elm dave ttyD4 9:47pm 4 4 w brent ttyp0 26Jun91 4:46 26:46 4:41 bash dave ttyq4 26Jun9115days 46 46 wnewmail | | | | | | | | ------------------------------------------------------------------------------- 9 6 10 6 7 7 35 Aşağıdaki program yukarıdaki girdiyi alır, idle sütunundaki zaman belirten verileri alır ve saniyeye çevirir ve birinci, ikinci sütun ile bu veriyi ekrana basar. Not: Bu program daha görmediğiniz awk kodları kullanmaktadır. |
]# awk'
> BEGIN { FIELDWIDTHS = "9 6 10 6 7 7 35" }
> NR > 2 {
> idle = $4
> sub(/^ */, "", idle) # baştaki boşluklar ayrılıyor
> if (idle == "")
> idle = 0
> if (idle ~ /:/) {
> split(idle, t, ":")
> idle = t[1] * 60 + t[2]
> }
> if (idle ~ /days/)
> idle *= 24 * 60 * 60
>
> print $1, $2, idle
> }' yukaridaki_veriler
-| hzuo ttyV0 0
-| hzang ttyV3 50
-| eklye ttyV5 0
-| dportein ttyV6 107
-| gierd ttyD3 1
-| dave ttyD4 0
-| brent ttyp0 286
-| dave ttyq4 1296000
|
|
gawk'de FS'ye değer atamak tekrardan FS'nin kullanılmasını sağlar. FS = FS kullanımı bunu yapar ve FS'nin o anki değerini bilmeye gerek yoktur. Alanların ayrılmasında hangi özelliğin aktif olduğunu öğrenmek için PROCINFO["FS"] ifadesini kullanabilirsiniz. PROCINFO["FS"] ifadesinden geri dönen değer "FS" ise alan ayıraçlarıyla, "FIELDWIDTHS" ise sabit uzunluk değerleriyle alanlar ayrılıyor demektir: if (PROCINFO["FS"] == "FS") alanlar alan ayıraçlarıyla ayrılıyor ... else alanlar sabit uzunluk tablosuna göre ayrılıyor ... FS ve FIELDWIDTHS arasında geçici olarak yapacağınız geçişler için yazacağınız bir fonksiyonda bu bilgi oldukça yararlı olacaktır. |
| 7.vii Çok Satırlı Kayıtlar Bazı veritabanlarında tek satır bir kaydı barındırmak için uygun değildir. Bu durumda çok satırlı kayıtlar kullanabilirsiniz. Bunu yaparken ilk adım veri formatını iyi seçmektir. Bir teknik, kullanılmayan karakterlerlerden vaya katarlardan birini kayıt ayıracı olarak seçmektir. Örneğin, formfeed karakterini kullanabilirsiniz (awk'de de C'deki gibi \f şeklinde yazılır). Bunu yaparken RS sabitine "\f" katarını atamalısınız. Başka diğer karakter aynı şekilde kullanabilirsiniz. Diğer bir teknik ise alanları ayırmak için boş satırlar kullanmanızdır. Kayıtları ayıran bir veya birden çok RS'nin gösterdiği boş katarlar özel bir dağıtma ile ayrılırlar. RS'ye boş bir katar atandığında herbir kayıt ilk rastgelen boş satırda son bulur. Sonraki kayıt ise ilk boş olmayan satıra rastlanmadığı sürece başlamaz. Satırda kaç tane boş satır bulunduğu önemli değildir ve hepsi bir kaydı ayırır. (boş satırlar tamamiyle boş olmalıdır.) RS'ye "\n\n+" değerini atayarak RS = "" ifadesinin etkisinin aynısını elde edebilirsiniz. Bu regexp, kaydın sonundaki yeni satırı ve kayıttan sonraki bir veya birden çok boş satırı eşleştirebilir. Ek olarak, regexp her zaman mümkün olan en uzun eşleştirmeyi yapar. RS = "" ve RS = "\n\n+" arasında önemli farklar vardır. İlk durumda, girdi veri dosyasındaki ilk kaydın en başındaki yenisatır karakteri yoksayılır ve dosyanın en son kaydının sonundaki boş satır dışında en son yenisatır karakteri kaldırılır. İkinci durumda, bu özel işlem yapılmaz. Şimdi sıra kayıtlara ayrılmış girdiyi alanlara ayırmaya geldi. Bunu yapmak için bir yol her satırdaki alanları normal şekilde bölmektir. RS'ye boş katar atandığında ve FS'ye de tek bir karakter atandığında yenisatır karakteri her zaman alan ayıracı olarak alınır. Bu ek duruma göre alan ayırma FS'den dönen değere göre yapılır. İstisnai bir durum için orjinal hareket öntanımlı durmda muhtemelen faydalı bir davranış olacaktır (örneğin FS'ye " " atamak). Bu şekil, eğer gerçekten alan ayıracı olarak yenisatır karakteri istemiyorsanız problem olur. Bununla birlikte, kayıtları el ile ayırmak için ayırma fonksiyonlarını kullanabilirsiniz. Eğer alan ayıracınız tek bir karakter ise özel bir kullanım şekli ile farklı bir yolla, FS'ye, o tek karakteri regexp içinde atayabilirsiniz. Örneğin, eğer alan ayıracı yüzde karakteri ise, yani FS = "%" ise o zaman FS = "[%]" ifadesini kullanmalısınız. Alanları ayırmak için bir diğer yol her alanı ayrı bir satıra yerleştirmektir. Bunu FS = "\n" ifadesiyle yapabilirsiniz. Aşağıdaki verilerin yerleşimine dikkat ediniz: adreslerJane Doe 123 Main Street Anywhere, SE 12345-6789 John Smith 456 Tree-lined Avenue Smallville, MW 98765-4321 ... Aşağıdaki gibi basit bir programla bu verileri işleyebilirsiniz:
# adres.awk --- basit posta listesi programı
# Kayıtlar boş satırlarla birbirlerinden ayrılmışlardır.
# Her satır bir alan.
BEGIN { RS = "" ; FS = "\n" }
{
print "İsim :", $1
print "Adres :", $2
print "Şehir ve Yer:", $3
print ""
}
Bu programı yukarıdaki verilerle çalıştıracak olursak aşağıdaki çıktıyı alırız: |
]# awk -f adres.awk adresler -| İsim : Jane Doe -| Adres : 123 Main Street -| Şehir ve Yer: Anywhere, SE 12345-6789 -| -| İsim : John Smith -| Adres : 456 Tree-lined Avenue -| Şehir ve Yer: Smallville, MW 98765-4321 -| ... |
|
Aşağıdaki tabloda, kısaca RS'nin kullanımı ile kayıtların nasıl ayrılacağı gösterilmiştir:
Bütün durumlarda gawk, RS ile eşleştirilen girdi kaydını RT'ye atar. |
| 7.viii getline İle Kesin Girdiler Şimdiye kadar, awk'nin ana girdi akışından (standart girdi veya dosyadan yapılan girdilerde) nasıl verileri alabildiğini gördük. awk dilinde özel fonksiyonları kullanarak girdi verilerini oldukça verimli bir şekilde kontrol altına alabilirsiniz. getline komutunu çok farklı değişik yollarla kullanabilirsiniz. İlerdeki getline komutununun içermesi gerekenleri açıklayıcı örneklerde henüz sahip olmadığınız birtakım bilgiler yer almaktadır. Bununla birlikte bu dökümanları bitirdikten sonra getline komutunu tekrar bir gözden geçirmeniz sizin, awk'nin çalışması hakkında iyi bir hakimiyet kurabilmeniz açısından yararlı olacaktır. getline komutu kayıt bulursa bir (1) değerini, dosya sonuna gelinmişse de sıfır (0) değerini geri döndürür. Eğer dosyanın açılamaması gibi bazı hatalarla karşılaşılırsa o zaman getline komutu eksi bir (-1) değerini geri döndürür. Bu durumda gawk ERRNO değişkenine meydana gelen hatayı tarif edici bir katar yükler. |
| 7.viii.1 getline'ın Parametresiz Kullanımı getline komutu o anki girdi dosyasından girdiyi okumak için parametresiz olarak kullanılabilir. Bu durumda yapılan işlemlerin hepsi bir sonraki girdi kaydını okur ve alanlar içinde onları ayırır. Eğer işlemi o anki kayıtta birtirmek istiyorsanız bu oldukça kullanışlıdır, fakat sonraki kayıtlar üzerinde bazı özel işlemler yapmak isteyebilirsiniz. Örneğin:
{
if ((t = index($0, "/*")) != 0) {
# 'tmp' nin değeri t 1 ise "" olacaktır.
tmp = substr($0, 1, t - 1)
u = index(substr($0, t + 2), "*/")
while (u == 0) {
if (getline <= 0) {
m = "beklenmedik EOF veya hata"
m = (m ": " ERRNO)
print m > "/dev/stderr"
exit
}
t = -1
u = index($0, "*/")
}
# substr ifadesi, satır sonunda */ a rastlanırsa "" olacaktır.
$0 = tmp substr($0, u + 2)
}
print $0
}
Bu program girdideki bütün C-stil (/* ... */) açıklamaları silmektedir. print $0 ile birlikte diğer ifadelerin yerlerini değiştirerek, yorumlanamayan girdiler üzerinde çok karmaşık işlemler yapabilirsiniz (regexplerle eşleştirme yapmak için aramalarda). (Bu programda gizli bir problem vardır--eğer bir açıklamanın sonu ile diğerinin başı aynı satırda ise o zaman program çalışmaz) getline komutunun bu şekli NF, NR, FNR, ve $0'ın değerlerini etkiler. Not: $0'ın yeni değeri sonraki bazı kuralların kalıplarını test etmek için kullanılmıştır. $0'ın orjinal değeri kuralı başlatmıştır, işletilen getline daha sonra değeri kaybetmiştir. Karşılaştıracak olursak sonraki ifade yeni kaydı okur fakat hemen doğal olarak baştan işlenir, program içinde ilk kural ile başlanır. |
| 7.viii.2 getline'ın Değişken İle Kullanımı getline'ı herhangi bir değişkene kayıt okumak için kullanabilirsiniz. Diğer işlemler devam etmez. Örneğin, sonraki satırı bir açıklama veya özel bir katar farzedelim ve siz onu başlatıcı bazı kurallardan ayrı olarak okumak istiyorsunuz. getline'ın bu şekli sizin o satırı okumanıza ve onu bir değişkene depolamanıza izin verir. Aşağıdaki örnek girdinin her iki satırını yer değiştirir:
{
if ((getline tmp) > 0) {
print tmp
print $0
} else
print $0
}
Aşağıdaki listeyi ele alalım:
wan
tew
free
phore
ve girdi olan o listenin işlenmiş hali:
tew
wan
phore
free
getline komutu bu yolla kullanıldığında sadece NR ve FNR değişkenleri yüklenir. Kayıt alanlara ayrılmaz, bu suretle alanların değerleri ($0'da bulunan) ve NF'nin değerleri değişmez. |
| 7.viii.3 getline'ı Dosyadan Kullanma getline < dosya ifadesini kullanarak dosyadan kayıt okuyabilirsiniz. Buradaki dosya bir katar ifadesidir ve dosya adını belirtir. < dosya farklı bir alandan başka bir dosyayı direk çağırmak için kullanılır. Örneğin aşağıdaki program o anki girdi kaydında, birinci alanı 10 olan bir kayıta denk gelirse o zaman ikinci.girdi isimli bir dosyadan girdi kaydı okur:
{
if ($1 == 10) {
getline < "ikinci.girdi"
print
} else
print
}
Çünkü ana girdi akışı kullanılmaz, NR ve FNR'nin değerleri değişmez. Bununla beraber, kayıt normal bir şekilde okunarak alanlara ayrılır, $0 ve diğer alanların değerleri değişir, NF'nin yeni değerinde belirtilir. POSIX'e göre, getline < ifadesi, eğer ifade $'dan başka parantezsiz operatörler içermiyorsa belirsizdir; örneğin getline < dir "/" dosya belirsizdir, çünkü sonuçları sıralayacak olan ifade parantezlerle ayrılmamıştır. Eğer programınızın diğer awk yorumlayıcıları ile uyumlu olmasını istiyorsanız bu ifadeyi getline < (dir "/" dosya) şeklinde yazmalısınız. |
| 7.viii.4 getline'ın Değişken İle Dosyadan Kullanımı getline var < dosya ifadesi ile dosya isimli dosyadan girdi okuyabilir ve bunu var isimli değişkene yazabilirsiniz. getline'ın bu şekli biçbir özel değişkeni etkilemez ve kayıt alanlara ayrılmaz. Yalnız var isimli değişken değişir. Örneğin, aşağıdaki program bütün girdi dosyalarını çıktıya kopyalar. Mesela kayıt, dosya adındaki dosyanın içeriği ile yer değiştirir:
{
if (NF == 2 && $1 == "@include") {
while ((getline line < $2) > 0)
print line
close($2)
} else
print
}
Burda önemli olan ekstra girdi dosyasının adının program içinde nasıl yapılanmadığıdır; bunlar veriden direk olarak alınır. @include satırında ikinci alanda bu belirtilmiştir. close fonksiyonu, eğer girdide iki aynı @include satırı ortaya çıkarsa programı emniyete almak için çağrılır, çünkü dosya iki kere dahil edilmek için belirtilmiş olabilir. Programdaki bir eksiklikte kümelenmiş @include ifadelerinin işlenememesidir (@include ifadeleri dosyaları dahil eder). |
| 7.viii.5 getline'ı Boru İşaretinden Gelen Çıktıyla Kullanma komut | getline ifadesi ile komutun çıktısı boru işareti sayesinde getline'a girdi olarak yollanır. Bu durumda 'komut' katarı kabuk komutu gibi çalıştırılır ve çıktısı awk'de girdi olarak kullanılmak üzere yollanır. getline'ın bu şekli bir anda borudan gelen bir kaydı okur. Örneğin, aşağıdaki program @execute ile başlayan satırlar için, bütün satırın kabuk komutu gibi çalıştırılması ile meydana gelen çıktıyla hangisi yer değiştirecekse onların girdi ve çıktılarını kopyalar:
{
if ($1 == "@execute") {
tmp = substr($0, 10)
while ((tmp | getline) > 0)
print
close(tmp)
} else
print
}
close fonksiyonu, eğer girdide iki aynı @execute satırı ortaya çıkarsa programı emniyete almak için çağrılır, komut her biri için çalıştırılır. Verilen girdi:
foo
bar
baz
@execute who
bletch
programın çıktısı böyle olmalıdır:
foo
bar
baz
arnold ttyv0 Jul 13 14:22
miriam ttyp0 Jul 13 14:23 (murphy:0)
bill ttyp1 Jul 13 14:23 (murphy:0)
bletch
Bu programın işletilmesi ile who komutunun işletilmesi gereken yerde b ukomutun çıktısı ile beraber diğer çıktılar ekrana basılırlar. (eğer siz programı deneyecek olursanız, sizin programınızın sizin sisteminize göre farklı bir çıktı verdiğini göreceksiniz.) getline'ın bu çeşidi kaydı alanlara ayırır, NF'nin değerini etkiler ve $0'ın değerinin yeniden hesaplanmasına neden olur. NR ve FNR'nin değerleri değişmez. POSIX'e göre, eğer ifade $ operatöründen başka parantezsiz operatörü kapsıyorsa ifade | getline belirsizdir. Örneğin, "echo " "date" | getline belirsizdir, çünkü sonuçları sıralayacak olan operatör parantezsizdir. Eğer programınızın diğer awk yorumlayıcıları ile uyumlu olmasını istiyorsanız bu ifadeyi ("echo " "date") | getline şeklinde yazmalısınız. |
| 7.viii.6 getline'ın Boru İşaretinden Gelen Çıktıyı Değişkene Atarak Kullanımı komut | getline var ifadesini kullanırsanız, komutun çıktısı borudan getline ve var değişkenine kadar gönderilir. Örneğin, aşağıdaki program o anki tarih ve saati, date aracını kullanarak o_anki_zaman değişkenine okur ve ekrana basar:
BEGIN {
"date" | getline o_anki_zaman
close("date")
print "Rapor ekrana basılıyor " o_anki_zaman
}
getline'ın bu şekilde kullanımı hiçbir özel değişkeni etkilemez ve kayıtları alanlara ayırmaz. |
| 7.viii.7 getline'ı Yardımcı İşlemciyle Kullanma Boru'dan getline'a girdi aktarmak sadece tek yollu operasyondur. Komut, komut | getline ile başlayan yalnız programınıza veri gönderen bir ifadedir. Verilerinizi diğer programlarda işlemek yollayabilmeniz ve geri çıktı olarak okuyabilmeniz için bir fırsat var. gawk iki yollu haberleşmeyi mümkün kılmak için yardımcı işlemciler ile başlamanıza müsaade eder. Bu |& operatörü ile yapılır. Tipik olarak, siz ilk önişlemci verisini ve o zaman okunacak geri çıktıyı aşağıda gösterildiği gibi yazarsınız:
print "some query" |& "db_server"
"db_server" |& getline
db_server sorgusu ve o zaman okunan çıktılardan hangisi gönderilmiştir. NR ve FNR'den hiçbiri değişmez, çünkü ana girdi akışı kullanılmaz. Bununla birlikte, kayıt normal şekilde alanlara ayrılmaz, bu suretle $0'ın değeri değişir, NF'de değişir. Yardımcı işlemci konusu uzmanlık ister, o yüzden bu konuya sadece kısaca değinmekle yetiniyoruz. Daha fazlasını öğrenmek istiyorsanız iki yollu girdi çıktı (Two-way I/O) konusunda araştırma yapınız. |
| 7.viii.8 getline'ın Yardımcı İşlemciyle Ve Değişkenle Kullanımı komut |& getline var ifadesini kullandığınızda, yardımcı işlemci komuttan gelen çıktı iki yollu borudan getline ve var değişkenine kadar gönderilir. getline'ın bu kullanımında hiçbir özel değişken etkilenmez ve kayıtlar alanlara ayrılmazlar. Yalnızca var değişkeni değişir. |
| 7.viii.9 getline Hakkında Hatırlanması Gereken Noktalar Burada getline hakkında hatırlamanız gereken önemli bazı noktalar yer almaktadır:
|
| 7.viii.10 Kısaca getline'ın Kullanımı Aşağıdaki tabloda getline'ın bütün kullanım şekilleri bir bir kısaca gösterilmiştir.
|
Yasal Açıklamalar:
Bu belgeyi, Free Software Foundation tarafından yayınlanmış bulunan GNU Özgür Belgeleme Lisansının 1.1 ya da
daha sonraki sürümünün koşullarına bağlı kalarak kopyalayabilir, dağıtabilir ve/veya değiştirebilirsiniz.
Bu Lisansın bir kopyasını http://www.gnu.org/copyleft/fdl.html adresinde bulabilirsiniz.
Linux, Linus Torvalds adına kayıtlı bir ticarî isimdir.
Feragatname:
Bu belgedeki bilgilerin kullanımından doğacak sorumluluklar, ve olası zararlardan belge yazarları
sorumlu tutulamaz. Bu belgedeki bilgileri uygulama sorumluluğu uygulayana aittir.
Tüm telif hakları aksi özellikle belirtilmediği sürece sahiplerine aittir. Belge içinde geçen herhangi bir terim
bir ticarî isim ya da kuruma itibar kazandırma olarak algılanmamalıdır. Bir ürün ya da markanın kullanılmış olması
ona onay verildiği anlamında görülmemelidir.
|