Yeni kullanıcılar için UNIX'e ilişkin ipuçları ve incelikler, Bölüm 3: Süzgeçlere ve düzenli ifadelere girişgrep, sed ve awk komutlarının kullanılması |
Düzey: Orta
Tim McIntire
(tm@timmcintire.net),
Danışman, Serbest Yazar
12 Mayıs 2006
UNIX® süzgeçlerinin gücünü keşfedin. Bu eğitici yazıda, birçok UNIX yardımcı programlarında düzenli ifade sözdizimlerini içerengrep
ailesiyle ilgili derinlemesine bilgi edineceksiniz. Örnekler ve açıklamalarlaawk
yapı tarama dilini incelerken, akım düzenleyicisiyle (sed
) ilgili bilgiler de öğreneceksiniz.
Başlamadan önce
Bu eğitici yazıdan neler öğrenebileceğinizi görün ve anlatılanlardan nasıl en iyi şekilde yararlanabileceğinizi öğrenin.
Dört bölümden oluşan bu eğitici yazı serisi, en temelden UNIX® konusunu
ele alır. Birinci eğitici yazı, UNIX benzeri işletim sistemlerinden bir süredir uzak
kalan kullanıcıların bilgilerini tazelemeleri için iyi bir fırsattı. Windows
başvuruları ve karşılaştırmaları kullanıldığı için bu eğitici yazı, Windows®
temelli yeni UNIX kullanıcıları için de yararlıdır. İkinci eğitici yazı, en güçlü
(ve gizemli) UNIX yardımcı programlarından biri olan vi
metin
düzenleyicisi üzerinde odaklandı. Bu eğitici yazıda, grep
,
sed
ve awk
süzgeçlerini içeren, düzenli ifadeleri
kullanan UNIX komut satırı süzgeçleriyle ilgili bilgiler anlatılacaktır.
grep
, sed
ve awk
gibi UNIX komut
satırı süzgeçlerinin arkasındaki gücü ortaya çıkarmak, sağlam bir düzenli ifade
gerektirir. Bu eğitici yazıda, yeni kullanıcılara bu yardımcı programların her
birinin neler yapabileceği ve metni işlemek için düzenli ifadelerin nasıl
kullanılacağı öğretilmektedir. Basit, eğlenceli grep
örneklerinden
başlayarak gerçek dünyayla ilgili sed
ve awk
örneklerine
geçeceksiniz.
Bu eğitici yazının amacı, UNIX ve Linux® kullanıcılarına, verileri hızlı
ve verimli bir şekilde aramak ve değiştirmek için kullanılabilecek üç güçlü komut
satırı aracını rahatça kullanabilmelerini sağlayacak bilgileri vermektir. Eğitici
yazının başlangıcında, birçok UNIX yardımcı programının (ve programlama dillerinin)
temel çerçevesinde kullanılan düzenli ifadeler açıklanır. Aşağıdaki bölümlerde,
grep
, sed
ve awk
ile düzenli ifadelerin
kullanılmasına ilişkin örnekler verilmektedir.
Bu eğitici yazı için komut satırıyla ilgili temel bir anlayışınız olmalıdır.
Bu eğitici yazının bazı bölümlerinde, stdin
, stdout
ve
pipe
komutlarıyla UNIX'te giriş ve çıkışın nasıl işlendiğine ilişkin
çalışmayı anlamak da yararlı olacaktır.
Bu eğitici yazıyı tamamlamak için gereksinim duyacağınız tek şey UNIX benzeri bir işletim sistemiyle çalışan herhangi bir bilgisayarda bulunan bir kullanıcı hesabına erişim olacaktır. UNIX benzeri işletim sistemleri, IBM AIX® işletim sistemini, Linux, Berkeley Software Distribution (BSD), Mac OS® X (komut satırına erişim için Uçbirim kullanır) ve daha birçok işletim sistemini içerir.
Düzenli ifadeler
Düzenli ifade, bir karakter dizesini aramak ya da değiştirmek için tasarlanmış başka bir karakter dizesidir. İlk bakışta, bu oldukça temel bir işlev gibi görünür. Çoğu kullanıcı, hemen her metin düzenleyicisindeki ya da sözcük işleme uygulamasındaki basit arama ve değiştirme işlevleriyle çalışabilir. Bu temel arama ve değiştirme işlevselliği bir hesap makinesiyle karşılaştırılırsa, düzenli ifadeler tam donanımlı bir bilgisayarla karşılaştırılabilir. Arama ölçütleri için düzenli ifadelerin kullanılmasının gücü hafife alınmamalıdır.
Düzenli ifadeleri kullanan süzgeçler
Düzenli ifadeler, grep
, sed
ve awk
(ve Perl'i içeren bazı programlama dilleri) gibi en güçlü UNIX tabanlı komut satırı
araçlarının bazıları tarafından kullanılır. Düzenli ifadelerin nasıl kullanılacağını
öğrenmek, UNIX komut satırı temel kullanıcısının gerçekten güçlü bir kullanıcıya
geçişi sırasında gerçekleştirilmesi gereken bir adımdır. Düzenli ifade
sözdizimlerinin birkaç farklı sürümü ve grep
, sed
ve
awk
komutlarının birden çok sürümü vardır; bu nedenle, bu eğitici yazı,
her bir uygulamada oldukça standartlaşmış en yaygın yapılar üzerinde odaklanır.
Sözdizimi ve komut satırı seçenekleriyle ilgili olarak sisteminizin man
sayfalarına bakmayı unutmayın.
Düzenli ifadeleri kullanan UNIX uygulamalarını keşfetmeden önce temel
noktaları öğrenmek önem taşır. Yalnızca bu bölümü okumanız yeterlidir. Daha sonra,
grep
bölümünde birkaç örnek deneyebilirsiniz.
Düzenli ifadeler, aramaya ilişkin ölçütleri gösteren özel karakterlerle
birleşen olağan karakter dizelerini kullanır. En temel durumunda, hiçbir özel
karakter kullanılmaz. Örneğin, arama ölçütü olarak golf
terimini
kullanmak istiyorsanız, aşağıdakini yazarsınız:
golf |
Bu düzenli bir ifadedir! golf
sözcüğünün tüm örnekleri aranır.
Düzenli ifadeler büyük/küçük harfe duyarlı olduğu için bu arama tüm
g olf
örneklerini bulur, ancak hiçbir
G olf
örneğini bulmaz.
Köşeli parantezlerin kullanılması
G olf
ve
g olf
sözcüklerinin ikisini birden aramak
için köşeli parantez kullanabilir (bunlar, düzenli ifadelerde özel karakterlerdir)
ve aranacak tek tek karakterler dizesini listeleyebilirsiniz. Bu, bir arama içinde
arama yapmaya benzer (düzenli ifadelerin arkasında yatan sihir de budur).
[Gg]olf |
Aynı kavram diğer karakter listeleri için de geçerlidir -- yalnızca
büyük/küçük harf ayrımı için kullanılmaz. Örneğin, golf
ve sizin
oluşturduğunuz yeni gelf
sporunu aramak isteyebilirsiniz:
g[oe]lf |
Şimdi, aramak istediğiniz üçüncü bir spor - gilf
- olduğunu
düşünün. Şimdiye kadar öğrendiklerinizin kullanıldığı bir yöntem, arama
ölçütlerinizde o
, e
ve i
harflerinin
kullanılmasıdır. Ama aramanız büyüdükçe, g
ile başlayan ve arada bir
karakter olduğu halde lf
ile biten her şeyi aramak isteyebilirsiniz.
Bunu yapmak için başka bir özel karakter olan noktayı (.) kullanın.
g.lf |
Bu, arada bir karakterin bulunduğu g
ile başlayan ve
lf
ile biten tüm dizeleri bulur. Aramanızı, g
ile başlayan
ve aralarında iki karakter olduğu halde f
ile biten tüm dizileri
bulacak şekilde genişletmek için iki nokta kullanabilirsiniz:
g..f |
Dosyaların grep ile aranması
Düzenli ifadelerin ardındaki kavrama ilişkin temel bir anlayışa sahip
olduğunuza göre bunların nasıl çalıştıklarını, gerçek dünyada karşılaşacağınız
örnekleri kullanarak göstermenin zamanı geldi. Denemeler yapacağınız ilk komut
satırı uygulaması grep
komutudur. grep
, gerçekte adını
g/RE/p
düzenli ifadesinden alır. grep
, belirli bir
dizenin örneklerinin bir ya da daha çok dosyada aranması için kullanılır. Varsayılan
değer olarak grep
komutu, arama dizesinin içinde göründüğü her bir
satırı görüntüler (arama dizesini kendi başına göstermez). Birden çok dosyada arama
yapıyorsanız, grep
uygulaması satırın bulunduğu dosyanın adını da
gösterir.
Aşağıdaki metni içeren grep.txt adlı bir dosya oluşturun:
I like golf. Golf is played on grass. I created gilf. |
grep
için temel sözdizimi şöyledir:
grep REGULAREXPRESSION FILENAME(S) |
Şimdi, düzenli ifadenin ilk örneğine, golf
sözcüğünün kendisine
dönün. Bu ifadeyi grep
ile kullanmak için aşağıdakini yazın:
grep golf grep.txt |
Bu komut, grep.txt dosyasında golf
dizesinin tüm örneklerini
arar ve dizeyi içeren satırları görüntüler. Çıkışınız aşağıdaki gibi olmalıdır:
I like golf. |
Köşeli parantezlerin kullanılması
Daha sonra, yukarıda anlatılan özel karakterlerin bazılarıyla denemeler
yapın. golf
ve Golf
sözcüklerini aramak istediğinizi
göstermek için köşeli parantezleri (bir köşeli parantez ifadesi) kullanabilirsiniz:
grep [gG]olf grep.txt |
Çıkış aşağıdaki gibidir:
I like golf. Golf is played on grass. |
golf
ve gilf
dizeleri için yine köşeli parantezleri
kullanabilirsiniz. Bunun yerine, g
ve lf
arasındaki aramak
istediğiniz karakterleri göstermek için bir nokta kullanmayı deneyin:
$grep g.lf grep.txt |
Çıkış aşağıdaki gibidir:
I like golf. I created gilf. |
golf, Golf ve gilf için arama yapılması
golf
dizesinin tüm farklı biçimlerini bulmanın yollarını
öğrendiniz, ancak aramalarınızın hiçbiri üç örneğin üçünü de döndürmedi:
golf
, Golf
ve gilf
. Üçünü birden nasıl
arayabileceğinizi düşünün. Bunu yapmanın birden çok yolu vardır. Aşağıda bu konuyla
ilgili birkaç örnek verilmiştir:
grep ..lf grep.txt grep [gG][oi]lf grep.txt |
Her iki yöntem de üç satırın üçünü de döndürür:
I like golf. Golf is played on grass. I created gilf. |
Bunu yapmanın başka yolu olabileceğini düşünüyor musunuz? Şimdiye kadar, düzenli ifadelerde kullanılabilecek yalnızca iki özel karakteri öğrendiniz. Bu yalnızca bir başlangıç! Bazı özel karakterler, diğer özel karakterlerin içinde kullanılır. Örneğin, bir karakter takımını köşeli karakterlerin içine yerleştirdiğinizde, bir karakter aralığını aramak için tire işaretini (-) kullanabilirsiniz. Aşağıdaki satırı metin dosyanıza ekleyin:
What is g2lf? |
Şimdiye kadar öğrendiklerinizle, g.lf
ya da
g[oi2]lf
gibi bir düzenli ifade kullanırsanız, bu satırın arama
sonuçlarında görüntüleneceğini biliyorsunuz. Bir konumdaki herhangi bir karakter
için noktanın kullanılması tüm sonuçları verir; [oi2]
seçeneğinin
kullanılması yalnızca, bu konumda o
i
ya da 2
olan örneklerin gösterilmesini sağlar. Birkaç karakterden daha fazlasını içeren,
ancak her karakteri içermeyen, tire işaretinin kullanıldığı üçüncü bir yöntem
uygulayabilirsiniz:
grep g[a-z]lf |
Bu yöntem aşağıdaki sonuçları görüntüler:
I like golf. I created gilf. |
Sonuçtan da görebileceğiniz gibi bu yöntem, a
ve z
arasındaki karakterleri (alfabetik sırayla) arar. Bu, g
ve
lf
arasındaki sayı ya da simgeleri içeren, gerçekte sözcük olmayan ve
büyük olasılıkla istediğiniz arama ölçütünüzün bir parçası olmayan dizileri dışlar.
Köşeli parantezlerin içindeki tire işareti
Köşeli parantezler içine başka karakter takımları ekleyerek birden çok
karakter dizilerini arayabilirsiniz. Örneğin, a-z
ve A-Z
örneklerini aramak için aşağıdaki aramayı kullanın:
grep g[a-zA-Z]lf |
Karakter dizilerinizin listesi uzadıkça, bulmak istediğiniz karakterleri
belirtmek yerine belirli karakterlerden kaçınmayı daha kolay bulabilirsiniz. Bunu,
arama dizinizden önce (köşeli parantezlerin içinde) şapka işaretini (^) kullanarak
gerçekleştirebilirsiniz. Anlatması biraz uzun olsa da aşağıdaki örneklerde bu
işaretin kullanımını kolay bir şekilde anlayacaksınız. Aramanızı sayısal değerler
dışındaki tüm karakterleri içerecek şekilde, grep
komutunu kullanarak
değiştirin:
grep g[^0-9]lf |
Bu arama, tüm alfabetik karakterlerin bulunduğu önceki aramalara benzerdir,
ancak bu aramada diyez işareti ( #
) ve dolar işareti ( $
)
gibi alfabede olmayan ve dışladığınız sayı dizisinde bulunmayan karakterler de
döner.
Deneme yapacağınız sonraki özel karakter, birkaç yineleme işleçlerinden biri olan yıldız (*) işaretidir. Çoğu insan, dosya adları için arama ölçütü olarak komut satırında yıldız işaretini (genel arama karakteri) kullanmıştır, ancak yıldız işaretinin düzenli ifadelerde kullanımı biraz daha farklıdır. Yıldız işareti, arama öğesinin (önceki karakter ya da köşeli parantez ifadesi) hiç geçmeyebileceğini, bir ya da birden çok kez geçebileceğini gösterir. Bunu denemek için üzerinde çalışmakta olduğunuz grep.txt dosyasına aşağıdaki satırları ekleyin:
This time the o is missing in glf. Some people might say goolf. But they would not say goilf. |
Tüm dosya aşağıdaki gibi görünür:
I like golf. Golf is played on grass. I created gilf. What is g2lf? This time the o is missing in glf. Some people might say goolf. But they would not say goilf. |
golf
sözcüğündeki o
karakterinden sonra yıldız
işaretini kullanmayı deneyin:
grep go*lf grep.txt |
Aramanız, golf
, glf
ve goolf
sözcüklerinin bulunduğu satırları verir:
I like golf. This time the o is missing in glf. Some people might say goolf. |
Diğer bir yineleme işleci soru işaretidir (?). Soru işaretinin işlevi, arama öğesinin hiç geçmemesi ya da bir kez geçmesi dışında yıldız işaretine benzer. Birden çok örnek eşlenmez. Az önce gerçekleştirdiğiniz aramayı yıldız yerine soru işareti kullanarak deneyin:
grep go?lf grep.txt |
Görebileceğiniz gibi eşleşen sonuç olarak golf
ve
glf
döndürüldü; ancak, soru işaretinden önce gelen o
arama
öğesinin birden çok örneği olduğu için goolf
sözcüğü döndürülmedi:
I like golf. This time the o is missing in glf. |
Genel yineleme işleçlerinin sonuncusu artı (+) işaretidir. Artı işareti, bir arama öğesi bir ya da daha çok kez geçtiğinde arama öğesini bulur. Yıldız işaretinden farklı olarak, eşleşme olması için öğenin en az bir kez geçmesi gerekir. Aşağıdaki örneği deneyin:
grep go+lf grep.txt |
Bu kez arama golf
ve goolf
sonuçlarını döndürür;
ancak, hiç o
bulunmadığı için glf
döndürülmez:
I like golf. Some people might say goolf. |
Satır başı ve satır sonu tutturucuları
sed
konusuna devam etmeden önce öğrenmeniz gereken son özel
karakterler, şapka işaretiyle kullanılan satır başı tutturucusu (anchor) ve dolar
işaretiyle kullanılan satır sonu tutturucusudur. Eğitici yazının önceki kısmında
şapka işaretini bir köşeli parantez ifadesini etkisiz duruma getirmek için
kullandığınızı hatırlayabilirsiniz. Şapka işareti köşeli parantezlerin dışındaysa,
tamamen farklı bir işlev gerçekleştirir. Bir düzenli ifadenin başına bir şapka
işaretinin konması, aramanın yalnızca satırın başında gerçekleşeceğini bildirir.
Diğer bir deyişle, düzenli ifadenizdeki (şapkadan sonraki) ilk karakterin, bu
satırla eşleştirmek üzere aranan yeni satırın ilk karakteriyle eşleşmesi gerekir.
Benzer bir şekilde, dolar işareti düzenli ifadenin sonuna, yalnızca satırın sonuyla
eşleşen sonuçların dönmesini istediğinizi belirtmek için yerleştirilir. Diğer bir
deyişle, düzenli ifadenizdeki (dolar işaretinden önceki) son karakterin, bu satırla
eşleştirmek üzere aranan yeni satırın son karakteriyle eşleşmesi gerekir. Bunu
sınamak için aşağıdaki iki satırı grep.txt dosyasına ekleyin:
golf has been a fine example let's talk about something besides golf |
Bu sınama için golf
sözcüğünde büyük harf ya da noktalama
kullanmamanız gerektiğini unutmayın; çünkü bu sınamada, tutturucular kullanılarak,
satırın sonunda ya da başında farklı bir şekilde çalışan aynı sözcüğe ilişkin bir
arama gösterilecektir. Satır başı tutturucusunu sınamak için aşağıdakini yazın:
grep ^golf grep.txt |
Çıkış aşağıdaki gibidir:
golf has been a fine example |
Satır sonu tutturucusunu sınamak için aynı aramayı kullanın, ancak bu kez
şapka işaretini kaldırın ve golf
sözcüğünden sonra bir dolar işareti
ekleyin.
grep golf$ grep.txt |
Satır sonu tutturucusunu kullanan çıkış aşağıdaki gibi görünür:
let's talk about something besides golf |
Komut satırında grep
komutunu kullanarak düzenli ifadelerin
temellerini öğrendiniz. Daha sonra, yalnızca metinde arama yapmayan, aynı zamanda
metni değiştiren sed
komutunu öğreneceksiniz. Öncelikle, şimdiye kadar
öğrendiklerinizi kısaca özetleyelim:
. Nokta, herhangi bir tek karakter yerine geçer. [] Köşeli parantezler, karakter dizilerini çevreler. - Tire, bir dizi oluşturmak için karakterler arasında kullanılır ([] içinde]). ^ Şapka, bir diziyi etkisiz duruma getirmek için kullanılır ([] içinde). * Yıldız, bir arama öğesinin sıfır, bir ya da birden çok örneklerini arar. ? Soru işareti, bir arama öğesinin sıfır ya da bir kez geçtiği örnekleri arar. + Artı işareti, bir arama öğesinin bir ya da birçok kez geçtiği örnekleri arar. $ Dolar işareti, satır sonunu arar. ^ Şapka, satır başını arar. \ Özel bir karakterden önce gelen sola eğik çizgi, bunu düz bir karakter yapa (Sonraki bölüme bakın.). |
Dosyaların sed ile düzenlenmesi
sed
, akım düzenleyicisi (stream editor) sözcüklerinin
kısaltmasıdır. Metin düzenleyicisinin geleneksel, modern tanımı metin dosyası
oluşturmak ve düzenlemek için kullanılabilecek etkileşimli uygulamadır.
sed
de bir metin düzenleyicisidir, ancak etkileşimli bir yardımcı
program yerine, bir komut satırı yardımcı programıdır ve bu özelliği onu, toplu
düzenleme için oldukça güçlü bir araç yapar. sed
, geniş metin dosyası
takımlarını süzen UNIX kabuk komut dosyalarında yaygın bir şekilde kullanılır.
Eğitici yazının ilk bölümünde, golf sözcüğünün bulunduğu küçük bir sınama
dosyası kullandınız. sed
düzenleyicisinin gelişmiş yeteneklerini
göstermek için, geliştiricinin toplu işlemde değiştirmek isteyebileceği küçük kod
bilgilerini kullanacaksınız.
Aşağıdaki metni sed.txt adlı bir dosyaya kopyalayıp yapıştırın:
system "echo 'project:$project' >> logfile"; system "echo 'version:$version' >> logfile"; system "echo 'optionalid:$optionalid' >> logfile"; system "echo 'nodes:$nodes' >> logfile"; system "echo 'threads:$threads' >> logfile"; |
grep
komutuyla kullanmak üzere anlatılan tüm özel karakterler
sed
ile de çalışır. Ancak, sed
olanağını kullanmak için ek
sözdizimleri öğrenmeniz gerekir. sed
içindeki temel ifade,
birbirinden sağa eğik çizgilerle (/) ayrılan dört bölümden oluşur. Bu, temel
sed
komutlarına ilişkin genel bir sözdizimidir:
sed s/REGULAREXPRESSION/REPLACEMENTSTRING/flags INPUT_FILE |
s
, bir ara ve değiştir komutu yürütmek istediğinizi
gösterir. Sağa eğik çizgiler, sed
içindeki düzenli ifadeleri
birbirine bağlamak için kullanılır. Örneğin, logfile
sözcüğünü
logfile.txt
olarak değiştirmek istiyorsanız, aşağıdaki komutu
çalıştırmanız gerekir:
sed s/logfile/logfile.txt/ sed.txt |
Çıkış aşağıdaki gibidir:
system "echo 'project:$project' >> logfile.txt"; system "echo 'version:$version' >> logfile.txt"; system "echo 'optionalid:$optionalid' >> logfile.txt"; system "echo 'nodes:$nodes' >> logfile.txt"; system "echo 'threads:$threads' >> logfile.txt"; |
Bu durumda dikkat edilmesi gereken önemli bir nokta, sed
programının sed.txt dosyasının içeriğini gerçekte değiştirmeyeceğidir. Bunun yerine,
çıkışı standart çıkışa gönderir. Bu örneklerde, işlemlerinizin sonuçlarını hemen
görebilmeniz için çıkışı standart çıkışa gönderirsiniz.
Sonra başvurularda çıkış yakalanabilir ve yeni bir dosyaya gönderilebilir. Örneğin, çıkışı sed_new.txt dosyasına göndermek için bu komutu çalıştırın:
sed s/logfile/logfile.txt/ sed.txt > sed_new.txt |
Eğik çizgileri öğrenirken, öğrenilmesi gereken başka bir çok önemli özel
karakter daha vardır. Ardından gelen karakter düzenli ifade yorumlamasından
kaçırdığı için sola eğik çizgiye (\) kaçış karakteri denir. Daha basit
anlatırsak, bir özel karakterin önüne sola eğik çizgi koyarsanız, karakter bir komut
öğesi yerine düz bir öğe olarak değerlendirilir. Birçok dosyada, özellikle kod
yazarken bu önemli bir şey olduğundan düzenli ifadeleri yürütmek için
kullanılanlarla aynı karakterlerin kullanımında büyük yarar sağlar. sed.txt
dosyanızda, dolar işaretinin kullanıldığı fark edersiniz. $project
sözcüğünü değiştirmek isterken, project
sözcüğünün kalmasını
istiyorsanız, ara ve değiştir komutunuzda kaçış karakteri kullanmanız gerekir:
sed s/\$project/\$project_name/ sed.txt |
Çıkıştan $project
sözcüğünün değiştirildiğini, ancak
project
sözcüğünün aynı kaldığını görebilirsiniz.
system "echo 'project:$project_name' >> logfile"; system "echo 'version:$version' >> logfile"; system "echo 'optionalid:$optionalid' >> logfile"; system "echo 'nodes:$nodes' >> logfile"; system "echo 'threads:$threads' >> logfile"; |
Bir öğenin birden çok örneğinin değiştirilmesi
Bu, sed
içindeki başka bir önemli özelliği ortaya çıkarır.
project
sözcüğünün iki örneğini de değiştirmek isterseniz ne olacak?
Şimdiye kadar öğrendiklerinizle, en mantıklı yanıt düzenli ifadenizde
project
sözcüğünü kullanmanız olacaktır, ki bu çok da doğru değildir.
Devam edin ve bu yöntemi deneyin; böylece, işlemi gözünüzde canlandırabilir ve
açıklayabilirim:
sed s/project/project_name/ sed.txt |
Çıkıştan project
sözcüğünün ilk örneğinin
project_name
olarak değiştirildiğini görebilirsiniz:
system "echo 'project_name:$project' >> logfile"; system "echo 'version:$version' >> logfile"; system "echo 'optionalid:$optionalid' >> logfile"; system "echo 'nodes:$nodes' >> logfile"; system "echo 'threads:$threads' >> logfile"; |
Ancak, ikinci örnek kesinlikle düzenli ifadenizle eşleşmesine rağmen
değiştirilmez. Birinci örnekten de bildiğiniz gibi sed
, birinci eşleşme
yerine tüm logfile
örneklerini değiştirdiği için girişindeki diziyle
eşleşen her diziyi değiştiriyormuş gibi görünür.
Buradaki farklılık logfile
örneklerinin ayrı bir satırda
bulunurken, project
örneklerinin aynı satırda bulunmasından
kaynaklanmaktadır. Bu durum neden bir fark yaratıyor? sed
, bir satır
düzenleyicisi olarak kullanılır. Satırların her biri, her defasında bir tane olacak
şekilde belleğe yerleştirilir ve tek bir birim olarak çalıştırılır. sed
uygulamasını çalıştırırken bunu aklınızdan çıkarmayın; çünkü, tüm komut satırı
seçenekleri bu tasarım felsefesiyle çerçevelenir (sed
uygulamalarının
çoğunda sistem belleğiyle ilgili dosya büyüklüğü sınırlaması olmamasını sağlar).
Varsayılan değer olarak her bir satır, sed
komutunun yeni bir yürütmesi
olarak işlenir. Birinci örnekte bu şekilde görünmese de her bir sed
komutu, eşleşen dizinin yalnızca birinci örneğini değiştirir. Ancak, siz bunu bir
g
işaretiyle kolayca değiştirebilirsiniz.
Aynı sed
komutunu, bu kez sonunda g
işaretiyle yürütün:
sed s/project/project_name/g sed.txt |
Bu kez, birinci satırdaki project
sözcüğünün iki örneği de
project_name
olarak değiştirilir:
system "echo 'project_name:$project_name' >> logfile"; system "echo 'version:$version' >> logfile"; system "echo 'optionalid:$optionalid' >> logfile"; system "echo 'nodes:$nodes' >> logfile"; system "echo 'threads:$threads' >> logfile"; |
g
harfi, global (genel) sözcüğünün kısaltmasıdır.
sed
komutunun başka bir güçlü özelliği de komutunuzu yürütmek
istediğiniz satırda olup olmadığını görmek için arama ve değiştirme işleminden önce
bir ön arama çalıştırmanızı sağlar. Bu, sed
içinde bir
grep
komutu çalıştırmaya benzer. Örneğinizde, node
değişkenine ilişkin günlük dosyasını diğer tüm çıkışla birlikte gruplamak yerine
değiştirmek isteyebilirsiniz. Bunu yapmak için logfile
dizisini
logfile_nodes
ile değiştirmek, ancak bunu, yalnızca düğümlerle ilgili
satırda gerçekleştirmek istersiniz. Bu komut da bunu yapar:
sed /nodes/s/logfile/logfile_nodes/ sed.txt |
Çıkış şöyledir:
system "echo 'project:$project' >> logfile"; system "echo 'version:$version' >> logfile"; system "echo 'optionalid:$optionalid' >> logfile"; system "echo 'nodes:$nodes' >> logfile_nodes"; system "echo 'threads:$threads' >> logfile"; |
İki nokta üst üste karakteriyle biten her dizenin değiştirilmesi
Şimdi, grep
komutunu kullanırken düzenli ifadelerle ilgili
öğrendiklerinizin bazılarını sed
komutunda kullanmayı deneyin.
sed
içinde aşağıdaki düzenli ifadeyi kullanarak iki nokta üst üste
karakteriyle biten her dizeyi değiştirebilirsiniz:
sed s/[a-z]*:/value:/g sed.txt |
Çıkış aşağıdaki gibidir:
system "echo 'value:$project' >> logfile"; system "echo 'value:$version' >> logfile"; system "echo 'value:$optionalid' >> logfile"; system "echo 'value:$nodes' >> logfile"; system "echo 'value:$threads' >> logfile"; |
Bu oldukça iyiydi, ama çok da mantıklı değildi. Çok mantıklı olmamasının
nedeni, hangi değişkenin hangisi olduğunu bilmeye imkan olmadan tüm
değişkenlerinizin önünde value
sözcüğünün bulunmasıydı. Ancak,
sed
komutunun başka bir özelliğini kullanarak bunu bir "gerçek dünya"
örneğine dönüştürebilirsiniz.
Ve işareti (&) düzenli ifadenizle eşleşen dizeyi gösterir. Diğer bir
deyişle, [a-z]*:
değerinin belirli bir satırdaki project:
sözcüğü olduğu ortaya çıkarsa, bu değerin yerini ve işareti alır. Bu oldukça yararlı
olabilir. Aşağıdaki örneğe bir bakın:
sed s/[a-z]*:/new_\&/g sed.txt |
Bu kez, eşleşen dizelerin her birini değiştirdiniz, ancak her bir değişkenle ilişkilendirilen tanıtıcıyı korudunuz:
system "echo 'new_project:$project' >> logfile"; system "echo 'new_version:$version' >> logfile"; system "echo 'new_optionalid:$optionalid' >> logfile"; system "echo 'new_nodes:$nodes' >> logfile"; system "echo 'new_threads:$threads' >> logfile"; |
Birden çok komut dizisinin yürütülmesi
sed
komutuyla bir defada birden çok şey de
gerçekleştirebilirsiniz. Bir defada birden çok komut dizisini yürütmek için her bir
ifadeden önce -e
işaretini kullanmanız gerekir. Varsayılan değer olarak
sed
, birinci bağımsız değişkeni ifade olarak yorumlar, ancak birden
çok komutu çalıştırırken daha açık olmanız ve -e
işaretini kullanmanız
gerekir. Örneğin:
sed -e s/[a-z]*:/value:/g -e s/logfile/name/g sed.txt |
Bu durumda sed
komutunun uygun yerlere value:
ve
name
sözcüklerini yerleştirdiğini görebilirsiniz:
system "echo 'value:$project' >> name"; system "echo 'value:$version' >> name"; system "echo 'value:$optionalid' >> name"; system "echo 'value:$nodes' >> name"; system "echo 'value:$threads' >> name"; |
sed
komutunun, büyük ölçekli toplu işlemlerde dosya düzenlemek
için çok güçlü bir araç olabileceğini görmeye başlamışsınızdır. Önceki örnekte,
grep
komutunda olduğu gibi tek bir dosyada çalıştınız. Bu yardımcı
programların gücünün bir kısmının, bu uygulamaların birden çok dosyada
çalışabilmelerinden geldiğini unutmayın. Bunu, bu eğitici yazıda kullanmakta
olduğunuz tek dosya yerine genel arama karakterleri ya da dosya listeleri kullanarak
gerçekleştirebilirsiniz.
Komut satırında awk komutunun kullanılması
Bu eğitici yazı, düzenli ifadelerin temel açıklamasıyla başladı ve ardından
grep
ve sed
komutları tanıtıldı. grep
, güçlü
bir arama, sed
de daha güçlü bir arama ve değiştirme yardımcı
programıdır. Sonraki adımda, tam donanımlı komut satırı programlama dilindeki
düzenli ifadeleri kullanan awk
gelir. sed
gibi
awk
da komut satırında kullanılır ve satır temelli girişi alır.
awk
, her defasında bir satırlık girişi yorumlar, ancak sed
komutundan farklı olarak, satırdaki her bir giriş parçasını iç koda ilişkin giriş ve
çıkış olarak kullanabileceğiniz değişkenler biçiminde işler.
AWK (büyük harfle), komut dosyaları yazmak için kullanabileceğiniz tam
donanımlı bir programlama dilidir (yalnızca komut satırında kullanılmaz), ancak bu
eğitici yazı, AWK komutlarını hızla yorumlayan komut satırı yardımcı programı olan
awk
üzerinde odaklanmaktadır.
Bu arada, bu yazıyı okuyan ve şimdiye kadar öğrendiklerinizin gerçek
dünyadaki yararlarını düşünenler varsa, birkaç iyi awk
örneği bulmak için
bazı eski kodlarda grep
ile arama yaptım:
grep awk */*.pl |
Sistem yöneticilerinin ve programcılarının çoğu, günlük kullanımda bu araçlardan yararlanırlar. Elde ettiğim çıkıştan birkaç örnek satırı aşağıda görebilirsiniz:
Edaemon/m_checkcurrentdisk.pl:$freespace = `awk '(NR==1) {print \$4 / 1024 / 1024}' grep.tmp`; Edaemon/m_getdatetime.pl:$month = `awk '(NR==1) {print \$2}' datetime.txt`; Odaemon/odaemon.beowulf.dvd.pl:$filesize = `awk '(NR==1) {print \$1}' temp.txt`; |
Bunlar, awk
komutunun çok temel kullanımını göstermesi açısından
iyi örneklerdir. İlk denemenizi kolaylaştıralım. awk
sınamalarınız için
boş bir dizinde aşağıdaki dosyaları oluşturun (her bir dosyanın içeriği ilgisizdir
ve boş olabilirler):
Screenshot_1.jpg Screenshot_2.jpg Screenshot_3.jpg awk.txt regular.txt sed.txt |
ls çıkışının awk girişi için kullanılması
Varsayılan değer olarak awk
komutu, giriş dosyasındaki her bir
satırı okur ve içeriği, boşluklarla belirlenen değişkenlere ayırır. Çok basit bir
örnekte, ls
çıkışını, awk
girişi olarak kullanabilir ve
sonuçları yazdırabilirsiniz. Bu örnekte, çıkışı awk
komutuna göndermek
için çubuk karakteri (|) bulunan ls
komutu kullanılır:
ls | awk ' { print $1 } ' |
Daha sonra, awk
her bir satırın ilk öğesini (bu durumda, her bir
satırdaki tek öğeyi) yazdırır:
Screenshot_1.jpg Screenshot_2.jpg Screenshot_3.jpg awk.txt regular.txt sed.txt |
awk için çok sütunlu bir giriş oluşturmak amacıyla ls -l komutunun kullanılması
Bu oldukça basit bir işlemdi. Sonraki örnekte, awk
için çok
sütunlu bir giriş oluşturmak amacıyla ls -l
komutunu kullanın:
ls -l |
ls
uygulamaları sistemden sisteme biraz farklılık gösterir,
ancak aşağıda örnek bir çıkış görebilirsiniz:
total 432 -rw-rw-rw- 1 guest guest 169074 Oct 15 14:51 Screenshot_1.jpg -rw-rw-rw- 1 guest guest 23956 Oct 15 20:56 Screenshot_2.jpg -rw-rw-rw- 1 guest guest 12066 Oct 15 20:57 Screenshot_3.jpg -rw-r--r-- 1 tuser tuser 227 Oct 15 20:16 awk.txt -rw-r--r-- 1 tuser tuser 233 Oct 15 19:35 regular.txt -rw-r--r-- 1 tuser tuser 227 Oct 15 23:16 sed.txt |
Dosya sahibinin her satırın üçüncü öğesi ve dosya adının her satırın
dokuzuncu öğesi olduğuna dikkat edin (öğeler awk
içinde varsayılan
değer olarak boşluklarla ayrılırlar). Her bir satırın üçüncü ve dokuzuncu öğelerini
yazdırarak bu listeden dosya sahibini ve dosya adını çıkarmak için awk
komutunu kullanabilirsiniz. Bu işlem aşağıda gösterilmiştir:
ls -l | awk ' { print $3 " " $9 } ' |
awk
içindeki print
komutunda iki tırnak işaretinin
ve bir boşluğun olduğunu fark etmişsinizdir. Bunlar, çıkışınızdaki dosya sahibi ile
dosya adı arasında bir boşluk yazdırmanız içindir:
guest Screenshot_1.jpg guest Screenshot_2.jpg guest Screenshot_3.jpg tuser awk.txt tuser regular.txt tuser sed.txt |
awk
yazdırma deyiminde bulunan değişkenler arasındaki
tırnakların içine metin yerleştirebilirsiniz.
Satırları belirtmek için düzenli ifadelerin kullanılması
awk
komutunun kullanılmasına ilişkin temel bilgileri
öğrendiğiniz, ancak bu eğitici yazı düzenli ifadelerle ilgili değil miydi?
awk
komutunda, düzenli ifadeler yoğun bir şekilde kullanılır. En yaygın
örneklerden biri, awk
komutunun ardından üzerinde çalışmak istediğiniz
satırları belirten düzenli bir ifadenin kullanılmasıdır. sed
komutunda
olduğu gibi awk
komutundaki düzenli ifadelerin önünde ve arkasında da
sağa eğik çizgiler bulunur. Örneğin, yalnızca tuser
kullanıcısının
sahip olduğu dosyalarda çalışmak isterseniz aşağıdaki komutu kullanabilirsiniz:
ls -l | awk ' /tuser/ { print $3 " " $9 } ' |
Komut aşağıdaki çıkışı oluşturur:
tuser awk.txt tuser regular.txt tuser sed.txt |
Dosya uzantılarının değiştirilmesi
Başka bir örnekte, resim dosyalarına dokunmadan metin dosyalarınızın her
birindeki dosya uzantılarını değiştirmek isteyebilirsiniz. Bunu yapmak için giriş
değişkenlerinizi boşluk yerine bir noktayla ayırmak isteyebilir ve daha sonra,
yalnızca metin dosyalarında arama yapmak istediğinizi gösteren bir düzenli ifade
kullanabilirsiniz. Değişkenleri noktaya dayalı bir şekilde ayırmak için
-F
işaretinin ardından tırnak içinde kullanmak istediğiniz karakteri
yazın. awk
çıkışı çubukla bir kabukta belirtilen (awk
tarafından oluşturulan komutları yürütür) aşağıdaki örneği deneyin:
s | awk -F"." ' /txt/ { print "mv " $1 "." $2 " " $1 ".doc" } ' | bash |
Sonraki ls -l
komutu yeni dosya adlarını gösterir:
-rw-rw-rw- 1 guest guest 169074 Oct 15 14:51 Screenshot_1.jpg -rw-rw-rw- 1 guest guest 23956 Oct 15 20:56 Screenshot_2.jpg -rw-rw-rw- 1 guest guest 12066 Oct 15 20:57 Screenshot_3.jpg -rw-r--r-- 1 tuser tuser 227 Oct 15 20:16 awk.doc -rw-r--r-- 1 tuser tuser 233 Oct 15 19:35 regular.doc -rw-r--r-- 1 tuser tuser 227 Oct 15 23:16 sed.doc |
Unutmayın, bunlar awk
komutuyla çalışmaya başlamak için gereken
temel bilgilerdir, ancak AWK, bu eğitici yazıda gösterilenden çok daha fazla
malzemeyi kullanabilen tam donanımlı bir programlama dilidir. awk man
sayfasına bakın. Daha çok bilgi almak için iyi bir kitaba bakmanız yararlı olabilir.
Özet
Bu eğitici yazıdaki örnekler, düzenli ifadelerin kullanıldığı UNIX
süzgeçlerini ve komut satırında nasıl kullanılabildiklerini temel olarak anlamanız
için yeterlidir. Kullanılan üç yardımcı program (grep
,
sed
ve awk
), bu eğitici yazıda anlatılan başlangıç
derslerindekinden çok daha ileri çeşitli yerleşik seçeneklere ve özelliklere
sahiptir. Yalnızca sed
ve awk
üzerine yazılmış kitaplar
vardır. Güçlü özellikleriyle ilgili bilgi almak için grep
komutundaki
man
sayfasına bakın.
Düzenli ifadelerin temelleri konusunda uzmanlaştığınızı düşünüyor ve sonraki adıma geçmek istiyorsanız, Perl, düzenli ifadeleri tam anlamıyla kullanan başka bir harika dildir. Perl ustaları, bu dile yabancı kullanıcıların anlamsız karakter dizeleri olarak gördükleri jilet inceliğinde, etkili kod satırları yazabilirler.
Bu dizinin tüm eğitici yazılarını izlediyseniz, komut satırında temel dosya
kullanımıyla, vi
metin düzenleyicisinin ve komut satırı süzgeçlerinin
nasıl kullanılacağıyla ilgili bilgileri öğrenmişsinizdir.
Bu dizinin sonraki eğitici yazısını bekleyin. O yazıda kabukla ilgili incelikler ve ipuçları ele alınacaktır. Bu arada, bu eğitici yazıda yer alan düzenli ifadelerle ve yardımcı programlarla ilgili öğrenebildiğiniz kadar bilgi öğrenin. Bunlar, uzun ve karmaşık görevleri, övünebileceğiniz kısa, etkileyici çözümlere dönüştürür!
Bilgi Edinme
-
Yeni
kullanıcılar için UNIX'e ilişkin ipuçları ve incelikler: Bu dizinin diğer
bölümlerini inceleyin.
- sed & awk
(O'Reilly, Mart 1997): Bu,
sed
veawk
ile ilgili daha fazla bilgi almak için iyi bir kaynaktır.
- AWK : Bu Web
sitesi AWK konusunu ayrıntılı bir şekilde ele alır.
- " Common
threads: Awk by example, Part 1 " (developerWorks, Aralık 2000): Bu makale,
awk
komutunu tanıtır ve bir programlama dili olarakawk
konusunu ayrıntılarıyla ele alır.
-
AIX
ve UNIX makaleleri : Tim McIntire tarafından yazılan diğer makalelere göz atın.
- AIX ve UNIX: UNIX
becerilerinizi geliştirmek için developerWorks AIX ve UNIX bölgesini ziyaret edin.
- AIX ve UNIX'te yeni
olanlar: AIX ve UNIX ile ilgili daha fazla bilgi almak için New to AIX and UNIX
(AIX ve UNIX'te yeni olanlar) sayfasını ziyaret edin.
-
developerWorks
teknik içerikli etkinlikler ve Web yayınları sayesinde güncel bilgiler
edinebilirsiniz.
-
AIX 5L
Wiki: AIX ile ilgili teknik bilgilere ilişkin bir işbirliği ortamı.
- Podcasts: İlgili
ayarları yapın ve IBM teknik uzmanlarının bilgilerine ulaşın.
Ürün ve teknoloji edinme
-
IBM
deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki
geliştirme projenizi oluşturun.
Tartışma
- AIX ve UNIX forumlarına katılın:
- AIX 5L -- teknik
- Geliştiriciler için AIX Forumu
- Küme Sistemi Yönetimi
- IBM Destek Yardımcısı
- Başarım Araçları -- teknik
- Sanallaştırma -- teknik
- Diğer AIX ve UNIX forumları
- developerWorks bloglarına ve developerWorks topluluğuna katılın.
Tim McIntire, HPCC yazılımları, desteği ve danışmanlığı konularında bir pazar lideri olan Cluster Corporation'ın danışmanı ve kurucu ortaklarındandır. Zaman zaman IBM developerWorks ve Apple Developer Connection'a da katkıda bulunmaktadır. Tim McIntire'ın Scripps Institution of Oceanography's Digital Image Analysis Lab'daki bilgisayar bilimleri çalışmasını yönetirken yürüttüğü araştırması, Concurrency and Computation ve IEEE Transactions on Geoscience and Remote Sensing gibi çeşitli dergilerde yayınlanmıştır. Ek bilgi için TimMcIntire.net adresini ziyaret edebilirsiniz. |