29/08/2003 Adana, v.0.1b
Düzenli ifadeler (regular expressions ya da regexp) belirli katarları tanımlamanın bir yoludur. awk programlamanın önemli bir parçası olan düzenli ifadelerin formatı ve kullanım şekilleri ayrıca bir konudur. Düzenli ifadeler, vi ve emacs gibi çoğu yazım işlemcilerinde, grep/ egrep gibi programların içerisinde ve awk, perl, ve sed gibi birçok dilde bulunabilir. Düzenli ifadeler, ileri seviyede içeriğe duyarlı aramalarda ve metin biçimlendirilmelerinde kullanılır. Bir düzenli ifade metin şeritine karşı eşleştirilen bir modelin biçimsel bir tanımlamasıdır. Metin yazımı ve saatler alan arama işi birkaç saniye içerisinde yapılabilir. Birkaç sözdizim kurallarını izlerler. Her ne kadar düzenli ifadeler Unix dünyasında oldukça geniş bir yayılıma sahipse de, "standart düzenli ifade dili" gibi birşey yoktur. Bu daha fazla birkaç farklı lehçeye benzer. grep programlarının örneğin iki çeşidi vardır; grep ve egrep. İkiside azıcık farklı yetenekleriyle düzenli ifadeleri kullanır. Perl, düzenli ifadelerin en eksiksiz kümesine sahiptir. Şansımıza, hepsi benzer kuralları izler. Temel düşünceyi anladığınız zaman, farklı lehçelerin detaylarını öğrenmek çok kolaydır. Bölü (/) işaretleri arasında yazılan düzenli ifadeler ile kayıttan süzülen veriler awk kalıbına göre seçilerek işlenirler. En basit düzenli ifade ardışık harfler, sayılar veya her ikisidir. Mesela regexp eşleştirmesi, herhangi bir katarı kapsar, ardışıktır. Böylece, mesela 'sel' regexp'iyle eşleştirilen herhangi bir katar 'sel' katarını kapsamaktadır. /sel/ kalıbıyla eşleştirilen herhangi bir girdi kaydı, kaydın içindeki herhangi bir yerde bu üç karakterli katarı ('sel') kapsıyordur. Regexplerin diğer çeşidi de sizin belittiğiniz, oldukça karmaşık katar sınıflarıdır. Öncelikle basit regexp örnekleriyle başlayacağız. Regexp'lerin çalışması hakkında geniş bilgiler vereceğimiz gibi çok karmaşık işlemlerin oluşturulması hakkında da örnekler sunacağız. |
6.i Düzenli İfadeler Nasıl Kullanılır Düzenli ifadeleri bölü karakterleri arasında bir kalıp gibi kullanabilirsiniz. Regexp herbir kaydın bütün yazısına karşı kontrol edilir. Örneğin aşağıdaki örnekte /er/ regexp'iyle eşleştirilen, yani bu iki karakteri ardışık bir şekilde kapsayan herbir kaydın ikinci alanı (sütunu) standart çıkışa yazılmaktadır. Daha önceki bölümde kullandığımız telefon_listesi isimli veri dosyasının içeriğini aşağıdaki gibi değiştirdik. telefon_listesiisim 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 ercan 2003/09/05 400 B kemal 2003/07/20 100 A erkan 2003/08/05 250 B recep 2003/08/02 230 C ertan 2003/07/04 550 B sami 2003/09/01 400 C halil 2003/08/05 450 B ersen 2003/07/05 650 B |
]# awk '/er/ { print "Tarih : "$2 }' telefon_listesi Tarih : 2003/09/05 Tarih : 2003/08/05 Tarih : 2003/07/04 Tarih : 2003/07/05 |
Düzenli ifadeleri, istersek kayıt içerisindeki tüm satırla, istersekte herhangi bir alanla karşılaştırma yapmak için kullanabiliriz. '~' ve '!~', regexp için karşılaştırma olanağı sağlayan iki operatördür. Bu operatörlerle kullanılan regexpleri, kalıplar gibi veya if, while, for ve do ifadeleri içinde kullanabiliriz. ifade ~ /regexp/Eğer belirtilen regexp eşleştirileceği sütunda varsa, o zaman olumlu sonuç üretilir. Aşağıdaki eşleştirme veya seçme işlemi, içinde küçük 'e' harfi bulunduran birinci sütun değerlerini standart çıkışa yazar : (Burada, birinci bölümde verdiğimiz ay_listesi isimli veri dosyası kullanılmaktadır.) |
]# awk '$1 ~ /e/' ay_listesi temmuz 15 425 0 eylul 30 500 1 ekim 60 525 1 |
Birde, aynı işlemi yapacak olan aşağıdaki kodu deneyebilirsiniz : |
]# awk '{ if( $1 ~ /e/ ) print }' ay_listesi |
ifade !~ /regexp/ Eğer belirtilen regexp eşleştirileceği sütunda yoksa, o zaman olumlu sonuç üretilir. Aşağıdaki eşleştirme veya seçme işlemi, içinde küçük 'e' harfi bulundurmayan birinci sütun değerlerini standart çıkışa yazar : |
]# awk '$1 !~ /e/' ay_listesi ocak 21 400 1 subat 21 425 2 mart 11 375 2 nisan 21 350 2 mayis 24 375 2 haziran 34 400 1 agustos 48 450 0 kasim 40 400 1 aralik 24 350 2 |
|
6.ii Karakter Kaçırma Katar veya regexsp sabitleri, bazı karakterleri harfi harfine kapsayamazlar. İşte bu özel karakterleri kaçırma karakteri ile birlikte göstermek gereklidir. Ve bu yazım şekli, önde tersbölü (\) sonrasında da kaçırılacak karakter ardışıklığıyladır. Örneğin kaçırma karakterini, bir katar sabiti içerisinde çift tırnak karakterini ekrana bastırmak istediğimiz zaman kullanmamız gerekir. Bu işlem '\"' yazım şekliyle yapılır. Böylelikle, çift tırnak karakterleri arasında yazılmış olan katar sabitini bölmeden, bu karakteri de katara dahil edebilmemize imkan tanınmış olur. Aşağıdaki gibi : |
]# awk 'BEGIN{ print "Bu katar sabitinin içine \" karakterini, \\\" şeklinde karakteri kaçırarak yazabildik" }' Bu katar sabitinin içine " karakterini, \" şeklinde karakteri kaçırarak yazabildik |
Yukarıda da kullandığımız gibi eğer tersbölü (\) karakterini, herhangi bir katar veya regexp sabiti içerisine yazmak istiyorsak o zaman bir tersbölü karakteri daha kullanarak (\\) bu karakteri kaçırabiliriz. '\' ve '"' karakterlerini ard arda kaçırmak istiyorsakta yine yukarıdaki örnekte olduğu gibi "\\\"" kullanımıyla bu karakterleri kaçırabiliriz. Başka bir kullanım şekli olarak, tab ve yenisatır karakterleri gibi görünmeyen karakterleride ifade edebilmek için tersbölü karakteri ile kaçırabiliriz. Bu tür karakterleri de, katar ve regexp sabitleri içinde, bu yöntemle kullanabilmemiz mümkün olmaktadır. Aşağıdaki tabloda, kaçırılması gereken bütün karakterler belirtilmekte ve açıklamaları da yanlarında yer almaktadır. Karakterleri, katar ve regexp sabitleri içinde uygulamaya çalışıp not almanızı öneririm. \\ Tersbölü karakteri, `\'. \a "alarm" karakteri, Control-g, ASCII kodu 7 (BEL). \b Backspace karakteri, Control-h, ASCII kodu 8 (BS). \f Formfeed karakteri, Control-l, ASCII kodu 12 (FF). \n Newline (yenisatır) karakteri, Control-j, ASCII kodu 10 (LF). \r Carriage return (satırbaşı) karakteri, Control-m, ASCII kodu 13 (CR). \t Horizontal (yatay) tab karakteri, Control-i, ASCII kodu 9 (HT). \v Vertical (dikey) tab karakteri, Control-k, ASCII kodu 11 (VT). \nnn Sekiz tabanında (octal) bir değer olan nnn, `0' ve `7' arasında üç tane rakamdan oluşur. Örneğin, ESC (escape) kaçırma karakteri nin ASCII kodu '\033'. \xhh... Onaltı tabanında (hexadecimal) bir değer olan hh, `0' ve `9' arasındaki bir rakam veya `A' ve `F' (`a' ve `f''de olabilir) arasındaki harflerden oluşabilir. ANSI C'de de aynı yapıya sahiptir. Kaçırma karakterinden sonra ki ilk gelen karakter olan 'x' karakteri sayını onaltılık düzende olduğunu belirtmektedir. Bununla birlikte ikiden fazla onaltı tabanında sayı belirtilirse, o zaman tanımsız olarak algılanacaktır. (`\x' kaçırmasını POSIX awk sağlamaz.) \/ Bölü karakteridir (yalnız regexp sabitleri için gereklidir). Bölü karakterini içeren bir regexp sabiti kullanırsak bölü karakterini bu şekilde kaçırabiliriz. regexp'ler bölü karakteri ile sınırlandırıldığından, bölü karakterini kalıbın parçası olarak kullanabilmek için bölü karakterini kaçırmak gereklidir. \" Çift tırnak karakteridir (yalnızca katar sabitleri için gereklidir). Bunu, katar sabitleri arasında çift tırnak karakterini kullanacağımız zaman uygulayabiliriz. Katar'ler çift tırnak karakteri ile sınırlandırıldığından, çif tırnak karakterini kalıbın parçası olarak kullanabilmek için bu karakteri kaçırmak gereklidir. gawk'de, ilaveten regexp'lere özel, tersbölü ile başlayan daha başka karakterler de vardır. Bunlara ilerde değineceğiz. Peki, katar sabitlerinde, yukarıda listelenmemiş karakterlerden birisi kullanılırsa ne olacaktır? POSIX awk, bu durumda o karakteri kaçırmayacaktır. Bunun için iki seçenek vardır :
regexp içinde, yukarıdaki listede tersbölüden sonra kullanılan ve gawk'nın tanıdığı özel regexp operatörleri içinde bulunmayan bazı karakterleri kullanırken, bunların önüne tersbölü karakteri getirdiğimizde awk bunu tersbölü karakteri yokmuş gibi algılayacaktır. Örneğin, /a\+b/ ifadesi "a+b" üç karakteriyle eşleştirilecektir. Tamamiyle uyumlu bir program oluşturmak için listelenmemiş karkterlerden önce tersbölü karakterini kullanmamalıyız. Regexp metakarakterlerini gösteriren octal ve hexadecimal kaçırma kullandığımızı farz edelim. awk, bu karakterleri regexp operatörümü yoksa karakter olarakmı algılayacaktır? Daha önce, karakterlerin harfi harfine alındığını görmüştük. Bununla beraber POSIX standartlarında, o karakterler gerçek metakarakterler olarak algılanacaktır (gawk'da ne yapıyorlarda o işi yapacaklardır). Compatibility (uygun) modda (Komut satırı parametrelerine bakınız), octal ve hexadecimal kaçırmaları regexp sabitleriyle kullanıldığında, gawk, bu octal ve hexadecimal sayılara karşılık gelen karakterleri algılayacaktır. Örneğin, /a\52b/ ifadesi, /a\*b/ ifadesine ya da /\x65\x72/ ifadesi, /er/ ifadesine karşılık gelecektir. Özetleyecek olursak :
|
6.iii Düzenli İfade Operatörleri Aşağıda metakarakter tablosu bulunmaktadır. Bu karkterleri regexplerin içinde kullanmak için kaçırma karakteri kullanmaya gerek yoktur. \ Özel karakterlerin eşleştirilmesi yapılacakken bu operatör kullanılır. Örneğin: \$ $ karakterinin eşleştirilmesi yapılmaktadır. ^ Bu operatör ile belirtilmiş katar, alanın başından itibaren aranacaktır. Örneğin : ^@bas "@bas" katarı alanın başında aranır. Önemli bir nokta da bu karakterin başka bir kullanım şeklidir. if() kalıbı içinde bir kontrol yapılacağı zaman kullanılmasına örnek olarak : if( "satır1\n\SATIR2" ~ /^S/ ) ... Burada "satır1\n\SATIR2" katarı 'S' karakteri ile başlıyorsa doğru yoksa yanşlış sonuç üretilecektir. $ Bu operatör bir önceki operatörün tam tersi olarak iş görür. Örneğin : son$ "son" katarı alanın sonunda aranır. Yine if() kalıbı içinde bir kontrol yapılacağı zaman kullanılmasına örnek olarak : if( "satır1\n\SATIR2" ~ /1$/ ) ... Burada "satır1\n\SATIR2" katarı '1' karakteri ile bitiyorsa doğru yoksa yanşlış sonuç üretilecektir. . Nokta operatörü, yerine herhangi bir karakter gelebileceğini belirtir. Örneğin : .P Bu ifade ile herhangi bir karakter ve sonra 'P' karakteri olan iki karakterli katarlar eşleştirmeye uyar. Mesela "U.A" ifadesi ile 'U' ile başlayan, sonra herhangi bir karakter olan ve sonunda da 'A' karakteri olan üç karakterli katarlar ifade edilir. POSIX modunda '.' operatörü NULL karakterle eşleştirilmez. [...] Bu operatör karakter listesini çağırır. Köşeli parantez ile kapalı bu ifade içindeki karakterler birer birer eşleştirilir. Örneğin : [MVA] İfadesi ile katar içinde 'M','V' veya 'A' karakterlerinden herhangi biri aranır. Bu operatörle bir aralık belirtilmek sureti ilede eşleştirme yapılabilir. [0-9] İfadesi 0 ile 9 aralığındaki bütün rakamlar için tek tek eşleştirme yapar. (0 ve 9 dahil) Çoklu aralık belirterekte eşleştirme yapılabilir. [A-Za-z0-9] İfadesinde bütün büyük ve küçük harfler ve 0-9 aralığındaki sayılar eşleştirilir. '\', ']', '-' veya '^' karakterlerini eşleştirmede kullanmak istersek, o zaman onları, önlerine \ karakteri koyarak kaçırmamız gerekmektedir. Örneğin : [B\]] İfadesinde 'B' ve ']' karakterleri eşeleştirme için kullanılacaktır. Mesela aşağıdaki gibi, POSIX standartlarına uyan özel karakter sınıflarınıda kullanarak eşleştirme yapabilmemiz mümkündür. Bu sınıfları "[:" ve ":]" ifadeleri arasında yazarız. [:alnum:] Alfanümerik karakter [:alpha:] Alfabetik karakter [:blank:] Boşluk veya tab karakteri [:cntrl:] Kontrol karakterleri [:digit:] Nümerik karakterler [:graph:] Ekrana basılabilir ve görünen karakterler (mesela boşluk görünemez) [:lower:] Küçük alfabetik karakterler [:print:] Ekrana basılabilen karakterler (Kontrol karakterleri değil) [:punct:] Noktalama karakterleri (harfler, rakamlar, kontorl kar. ve boşluk kar. değil) [:space:] Boşluk karakterleri (boşluk, tab, formfeed vs. gibi) [:upper:] Büyük alfabetik karakterler [:xdigit:] Karakterlere karşılık gelen hexadecimal sayılar Karakter listesinde ortaya çıkan iki özel nokta daha vardır : - Sembolleri Karşılaştırarak Okuma '[.' ve '.]' aralığında çoklu karakter karşılaştırılmaktadır. Örneğin : 'ch' karşılaştırılacak eleman olsun, [.ch.] regexp eşleştirmesi ile 'c' veya 'h' karakterlerinin olduğu alanlar eşleştirmeye uyar. - Sınıflara Eşitleme Yerel karakter listeleri için eşleştirme yapılır. '[=' ve '=]' aralığında belirtilir. Örneğin : 'e' karakteri kullanıldığında "e,", "è" ve "é" harfleri ile de eşleştirme yapılacaktır. [=e=] regexp eşleştirilmesi "e", "è" ve "é" harflerini de içeren alanlarıda alacaktır. Bu şekiller İngilizceden farklı bir dilde çok faydalı olabilir (Mesela ikinci kullanım, Fransızcada). [^ ...] Bu operatör, ... ile belirtilen karakterler haricinde eşleştirme yapar. Örneğin : [^0-9] ifadesi içinde rakam bulunmayan alanlarla eşleştirilir. | Bu operatör ile birbirini takip eden ifadeler kullanılabilir. Örneğin : ^P|[0-9] ifadesi ile 'P' karakteri ya da 0-9 aralığındaki herhangi bir rakam ile başlayan alanlar eşeleştirmeye uyar. (...) Bu operatör regexler içinde gruplama yapmak için kullanılır. Bu operatör içindeki ifadeleri '|' işareti ile birbirlerinden ayırıp sıralayarak kullanabiliriz. Örneğin : `(er|ok)' ifadesi ile "er" veya "ok" ile başlayan alanlar eşleştirilecektir. * Bu operatör, önündeki karakterlere göre işlem yapar. Çoğu zaman tekrarlanmış karakterleri bulmak için kullanılır. Örneğin : er* ifadesi 'e' ve onu takiben 'r' karakterlerini bulunduran, ayrıca sadece 'e' karakterlerini de bulunduran alanları eşleştirir. Yani, alanda 'e' harfi yoksa 'r' harfinin bulunması birşey ifade etmez. Örneğin : kan* ifadesindeki gibi üç tane karakter belirttiysek, o zaman operatör "ka" katarını veya "kan" katarını bulunduran ifadeleri eşleştirecektir. Mesela : awk '/\(c[ad][ad]*r x\)/ { print }' veri ifadesinde awk, "(car x)", "(cdr x)", "(cadr x)" ve "(caar x)" katarlarını bulunduran katarları eşleştirecektir. Bu ifade de parantezlerden ( '(' ve ')' ) önce '\' karakterini kullandığımıza dikkat ediniz. ca*t ifadesinde ise "ct", "cat", "caat", "caaat", ... gibi katarları bulunduran alanlar eşleştirmeye uyar. + Bu operatör '*' operatörüne benzerdir, fakat önündeki karakterin en az bir kere eşleştirilmesi şarttır. ca+t ifadesinde 'a' karakterini en az bir veya birden fazla ard arda bulunduran, bu harfin önünde de 'c' harfi bulunan ve ardında da 't' harfi bulunan alanlar eşleştirmeye uyar. Mesela "cat", "caat", "caaat", ... gibi katarları bulunduran alanlar eşleştirmeye uyar ancak "ct" katarını bulunduranlar uymayacaktır. Eğer "ca*t" ifadesini kullanmış olsaydık o zaman "ct" katarını bulunduran alanlarda eşleştirmeye uyacaklardı. awk '/\(c[ad]+r x\)/ { print }' veri ifadesi "awk '/\(c[ad][ad]*r x\)/ { print }' veri" ifadesiyle aynı sonucu verecektir. ? Bu operatör de '*' operatörüne benzerdir, fakat bunda da operatörün önündeki karakterden en fazla bir tane olması gerekmektedir. Örneğin : ca?t ifadesinde 'a' harfini bir kere bulunduran veya hiç bulundurmayan ifadelerler eşleştirme yapılır. Mesela "ct" ve "cat" katarlarını bulunduran alanlar bu eşleştirmeye uyarlar. {n} {n,} {n,m} Operatörleri önceki üç operatöre benzemektedir. Bu operatörlerle önüne gelen karakterin tekrar edilme miktarları belirtilerek eşleştirme yapılır. Örneğin : ca{3}t ifadesiyle "caaat" katarını bulunduran alanlar eşleştirilir. "cat", "caaaaat", ... gibi katarları içeren katarlar eşleştirilmez. Yani sadece üç tane 'a' bulunduran anlamındadır. ca{2,4}t ifadesiyle sadece "caat", "caaat" ve "caaaat" katarlarını bulunduran alanlar eşleştirilir. Yani iki ile dört arası mitarda 'a' bulunduran anlamındadır. ca{2,}t ifadesiyle ise "caat", "caaat", "caaaat", ... gibi katarları bulunduran alanlar eşleştirilir. Yani iki veya daha fazla mitarda 'a' bulunduran anlamındadır. Aralık ifadeleri standart awk'de mevcut değildir. Birbirine uyumlu olarak birlikte çalışabilen awk ve egrep beraberce POSIX standartları parçası olarak kullanılabilmiştir. Aralık ifadelerini, öntanımlı gawk programlarında kullanırsak eşleştirme yapılmayacaktır. regexp'lerde bu aralık ifadeleri kullanılarak eşleştirme yapılabilmesi için gawk'de '--posix' veya '--re-interval' parametrelerini kullanmamız gerekmektedir. Örneğin : gawk --posix '/ca{2,4}t/' veri gawk --re-interval '/ca{2,4}t/' veri Düzenli ifadelerde '*', '+' ve '?' operatörleri '{' ve '}' operatörlerine göre yüksek önceliklidir ve son olarakta '|' operatörü gelir. Fakat prantezler ( '(' ve ')' ) kullanıp gruplama yapılarak bu öncelikler değiştirilebilir. |
6.iv gawk'ya Özel Regexp Operatörleri GNU yazılımları regexpler ile iş yapılırken ek regexp operatörleri sağlarlar. Aşağıdaki operatörler sadece gawk'ya özgüdür ve diğer awk yorumlayıcılarında mecvut değildirler. Çoğu operatör kelime eşleştirme işlemleri ile ilgilidir. Bizim amacımız, bir veya birden çok harf, rakamlar veya alt çizgi ('_') içeren kelimeleri eşleştirmektir. \w Bu operatör ile herhangi bir harf, rakam veya alt çizgi içeren kelimeler eşleştirilir. Aynı işlemi yapan [[:alnum:]_] yerine daha pratik bir kullanım sunar. \W Bu operatör ile herhangi bir harf, rakam veya alt çizgi içermeyen kelimeler eşleştirilir. Bu operatörde aynı işlemi yapan [^[:alnum:]_] yerine daha pratik bir kullanım sunar. \< Bu operatörün ardında belirtilen katarla birebir eşit olan alanlar eşleştirmeye uyar, fakat sonunda bulunduran alanlar eşleştirmeye uymaz. Örneğin : /\<lik/ ifadesinde "lik" katarı eşleştirmeye uyar ama "kalemlik" katarı uymaz. \> Bu operatörden önce belirtilen katarla birebir eşit olan alanlar eşleştirmeye uyar, fakat başında bulunduran alanlar eşleştirmeye uymaz. Örneğin : /\<kalem/ ifadesinde "kalem" katarı eşleştirmeye uyar ama "kalemlik" katarı uymaz. \y Başta ve sonda kullanılmasına göre sonuç değişir. Eğer seçim katarının başında kullanılırsa o zaman baştan itibaren bu katarı barındıran alanlar, eğer seçim katarının sonunda kullanılırsa o zaman sondan itibaren bu katarı barındıran alanlar eşleştirmeye uyarlar. Örneğin : /\ysayı/ ifadesiyle "sayı", "sayılar", ... gibi alanlar, /lar\y/ ifadesiyle "lar", "sayılar", ... gibi alanlar, /\ysayı?\y/ ifadesiyle ise hem "say" hemde "sayı" ifadesine denk alanlar eşleştirmeye uyarlar. \B Bu operatörün de işlevi başta ve sonda kullanılmasına göre değişir. Eğer seçim katarının başında kullanılırsa, başı hariç başka herhangi bir yerinde bu katar bulunan veya seçim katarının sonunda kullanılırsa, sonu hariç başka herhangi bir yerinde bu katar bulunan alanlar eşleştirmeye uyarlar. Eğer seçim katarı bu operatörün ikisi arasında yazılmışsa o zaman da başında ve sonunda bu katar bulunmayan alanlar eşleştirmeye uyarlar. Örneğin : /\Bklav/ ifadesiyle "oklava", "baklava", ... gibi alanlar eşleştirmeye uyar, fakat "klavye", ... gibi alanlar uymaz, /cere\B/ ifadesiyle "cereyan", "cereme", ... gibi alanlar eşleştirmeye uyar, fakat "tencere", ... gibi alanlar uymaz, /\Bkal\B/ ifadesiyle ise "tokalı", "bakalit" ... gibi alanlar eşleştirmeye uyar, fakat "kalfa", "bakkal", ... gibi alanlar ve "kal" alanı eşleştirmeye uymazlar. Ayrıca, tamponlar (buffer) üzerinde işlem yapan iki tane daha operatör vardır. Emacs'te kullanılan tamponlar Emacs tamponlarıdır. Fakat diğer programlar için, regexp işlemleri, mesela gawk'yi düşünecek olursak girilen katarın eşleştirilmesi tamponda yapılır. awk için '^' ve '$' operatörleri her zaman katarın başı ve sonuyla işlem yaparlar. Bu operatörler ek yeni yetenekler getirmezler. Sadece diğer GNU yazılımlarına uyum sağlayabilmesi içindir. \` Bu operatör tamponun başındaki boş katarları eşleştirir. \' Bu operatör tamponun sonundaki boş katarları eşleştirir. Diğer GNU yazılımlarında '\b' (boundary) sınır operatörüdür, fakat farklı olarak gawk'de ve diğer awk yorumlayıcılarında '\b' karakteri geriboşluk (backspace) olarak tanımlanmıştır. Birkaç komut satırı parametresi ise gawk'de regexp'ler içindeki bazı karakterlerin nasıl yorumlanması gerektiğini belirtir. Parametre yoksa Öntanımlı seçenekte gawk, bütün POSIX regexplerinin sağladığı imkanları ve yukarda tanımlı GNU regexp operatörlerini sağlar. Bunula birlikte aralık ifadelerini desteklemez. --posix Yalnızca POSIX regexpleri sağlanır, GNU operatörleri geçersiz olur (mesela, '\w' operatörü 'w' harfi olarak algılanır). Aralık ifadeleri de desteklenir. --traditional Standart Unix awk regexpleri eşleştirilir. GNU operatörleri, aralık ifadeleri ve POSIX karakter sınıfları ([[:alnum:]] ve diğerleri) desteklenmez. Karakterler, o karakter yerine geçen octal ve hexadecimal kaçırma ifadeleri ile tanımlanmıştır. regexp metakarakterlerini gösteriyorlarsa bile. --re-interval regexplerde aralık ifadelerine izin verilir, hatta `--traditional' sağlanmışsa bile. |
6.v Eşleştirmede Büyük Harf-Küçük Harf
Hassasiyeti Seçim genellikle, alışılmış karakterler eşleştiriliyorken (metakarakterler değil) regexpler içinde anlamlıdır. Bunun için 'w', düzenli ifadenin içinde 'w' karakteri ile eşleştirilirken 'W' karakteri ile eşleştirilmez. Bu eşleştirme hatasına düşmemek için istenilen karakterler liste olarak verilebilir. '[Ww]' listesini belirtmek işimizi oldukça kolaylaştıracaktır. Fakat sık sık bu hantal kullanımı uygularsak regexp ifadelerinin okunmasını çok zorlaştırabiliriz. Bunun yerine tercih edebileceğiniz iki alternatifiniz bulunmaktadır. Birinci yol, alanlardaki alfabetik karakterleri büyük veya küçük harflerine çevirebilen fonksiyonları kullanmaktır. Örneğin : tolower($1) ~ /sel/ { ... } # eşleştirmeden önce 1. alandaki karakterleri küçük yapar toupper($1) ~ /sel/ { ... } # eşleştirmeden önce 1. alandaki karakterleri büyük yapar Bu bütün POSIX awk'lerle uyumludur. Diğer yolsa gawk'ye özel bir değişken olan IGNORECASE değişkeniyle ilgilidir. Bu metodda IGNORECASE değişkenine sıfırdan farklı bir sayı atarsak gawk, bütün regexp ve katar işlemlerinde büyük-küçük harf ayrımı yapmayacaktır. Eğer IGNORECASE değişkenine sıfır değerini atarsak gawk büyük-küçük harf ayrımı yapacaktır. IGNORECASE değişkenine programın çalışma zamanında atama yapabiliriz. Bu değişken öntanımlı olarak sıfır değeri ile yüklüdür. x = "aB" if (x ~ /ab/) ... # bu test yanlış sonucu üretecektir. IGNORECASE = 1 if (x ~ /ab/) ... # şimdi başarılmıştır. Fakat IGNORECASE değişkenine değer atama metodu programın taşınabilirliği açısından ve belirli kalıp kurallarına uyumlu herhangi bir işlem yapılmıyor olunduğundan kullanılması pek tavsiye edilmez. Onun yerine tolower() ve toupper() fonksiyonlarını kullanmak daha sağlıklıdır. gawk 3.0 sürümünden önce IGNORECASE değişkeninin değeri yalnızca regexp ifadelerini etkilerdi. Katarları "==" ve "!=" ile karşılaştırmalarında etkisi olmazdı. 3.0 sürümüyle birlikte hem regexp ifadelerinde hemde katar karşılaştırmalarında etkili olmaya başladı. gawk 3.0 sürümüyle birlikte, küçük-harf ve büyük-harflerin arasındaki karakterler ISO-8859-1 (ISO Latin-1) karakter seti temeline dayanmaktadır. Bu karakter seti, geleneksel 128 ASCII karakterleri süpersetidir. Bu set Avrupa dilleri ile kullanım için uygun karakterleri bile sağlar. IGNORECASE değişkeni, eğer gawk compatibility modda çalışıyorsa etkisizdir. Büyük-küçük harf ayrımı compatibility (uygun) modda her zaman anlamlıdır. |
6.vi Ne Kadar Yazı Eşleştirilebilir? Aşağıdaki örneği uygulayarak ne yaptığı hakkında biraz düşünün : |
]# echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }' |
Bu örnek, girdi değerini değiştiren sub() fonksiyonunu kullanır (katarları işlemek için kullanılan bu awk fonksiyonunu ilerde ayrıntılarıyla göreceğiz). Burda, /a+/ regexp'i "bir veya daha çok 'a' karakterini" arar ve "<A>" değeriyle değiştirir. Girdi 'a' krakterlerini kapsar. Çıktı ne olur? Girdi içinde "bir veya daha fazla" yani, awk bir, iki, üç, veya dört tane 'a' karakteri eşleştirdi? awk (ve POSIX awk) regexp'leri genellikle soldan itibaren eşeleştirmeye başladığından, bu girdide uzun bir ardıllıkla 'a' karakteri ile eşleştirme yapılmıştır. Böylelikle, örnekte, ardışık dört 'a' karakterinden oluşan katar "<A>" katarıyla değiştirilmiştir. |
]# echo aaaabcd | awk '{ sub(/a+/, "<A>"); print }' <A>bcd |
Bu temel eşleştirme/eşleştirmeme testleri pek önemli değildir. Fakat, yazı eşleştirmesi ve sub(), gsub(), ve gensub() fonksiyonlarıyla yerine-koyma, alan ve kayıtlarda regexp-tabanlı bölme işlemleri ile yapılıyorsa o zaman çok önemlidir. |
6.vii Dinamik Regexplerin Kullanımı '~' veya '!~' operatörünün sağ tarafına gelecek ifadenin, regexp sabiti olması şart değildir (mesela bölü karakterleri arasındaki karakter katarı). Bu herhangi bir ifade olmalıdır. İfadeyi (katarı) bir değişkene atayarak gerekli işlemleri yapabiliriz. Katarın içeriği regexp gibi kullanılabilir. Regexp bu yolla, işlenmek için dinamik olarak çağrılabilir. Örneğin : BEGIN { regexp_tanimlayici = "[A-Za-z_][A-Za-z_0-9]+" } $0 ~ regexp_tanimlayici { print } Burda regexp_tanimlayici adıyla tanımladığımız awk değişkenine atadığımız regexp ifadesini, girdi kayıtlarıyla karşılaştırarak uyumlu kayıtları ekrana bastırdık. Not : '~' ve '!~' operatörlerini kullanıyorken, regexp sabitlerini bölü karakterleri arasında yazmaktan farklı bir şekilde çift tırnak arasında katar sabitleri şeklinde yazarız. Eğer katar sabitlerini kullanıyorsanız, bu iki ana özelliğin özünü anlamış olmalısınız; ilk anda awk programı okur ve ikinci anda da operatörün sol tarafındaki değerle sağ tarafındaki kalıp üzerinde katar eşleştirmesi yapar. Bu ifade katar değerli ifadedir fakat bir katar sabiti değildir (yukarıdaki regexp_tanimlayici değişkeni gibi). Katar taraması yapılırken farklı olan nedir? Cevap, kaçırma karakterleri ile, özellikle tersbölü ile birlikte belirlenen katarlarda farklılıklar vardır. Çünkü bu katar sabitleri olarak tanımlı regexp'ler içinde tersbölü karakterini kullanıyorken iki terbölü karakteri yazmamız gereklidir. Örneğin; /\*/ ifadesi '*' karakteri için regexp sabitidir. Yalnız tek tersbölü'ye ihtiyaç vardır. Katar sabitinin de regexp sabiti ile aynı işlemi yapmasını istiyorsak "\\*" şeklinde bir kullanım uygulamalıyız. Birinci tersbölü karakteri ikinci tersbölü karakterini kaçırmak için kullanılmıştır. Bu kaçırılan ve böylelikle sadece tersbölü karakteri anlamına gelecek olan karakter de '*' karakterini kaçırmak için kullanılmıştır. Yani bu katarla aslında hm '\' hem de '*' karakterleri kaçırılmıştır. regexp ve katar sabitlerinin her ikisi de regexp ifadesi olarak tanımlanabilir, fakat hangisini kullanmak daha gereklidir? Cevap, aşağıdaki birkaç sebepten dolayı "regexp sabitleri"'dir.
|
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. |
Teknik Bilgiler
Bilgisayar, Linux, Internet, WWW
http://teknik.ekitap.gen.tr/