awk Komutu ve Kullanımı

awk, grep ve sed'e benzer şekilde, örüntü temelli tarama ve işleme dilidir.

AA

nawk ve gawk adında daha gelişmiş yeni versiyonu ve alternatifi bulunur. Komut kullanımında dosyadaki her satır satır ve sütun olarak ayrıştırılır1 ve döngü sonunda örüntüye uygun olarak sunulur. Temel işlem olarak kelimeler satır içerisindeki boşluklara göre ayrıştırılır ve sıralamasına göre referans değeri alır. Örn. $1: (ilk değişken), $2 (ikinci değişken), … $n (n değişken)

awk Kullanımı

Örnek kullanımlar için space-separated veri yığınına ihtiyacımız var.

Ad Soyad Yaş Şehir Cinsiyet
Ad Soyad Yaş Şehir Cinsiyet
Ali Kara 20 Edirne E
Burcu Yılmaz 33 Kars

Murat Durmuş 27 Antalya
   30 K
Ayşe Karagül 22 Mardin K

Örnekte de görüldüğü üzere oldukça basit ve temiz bir veriye sahibiz. Bu sayede satır içerisindeki boşlukları kolaylıkla ayrıştırıcı olarak kullanabiliriz. Boşluklara göre satır ve sütunları değerlendirdiğimizde Ad = $1, Soyad = $2, Yaş = $3 ve Şehir = $4 olacaktır. İlk örneğimiz ad sütunundaki $1 değerlerini, yani kişi adlarını görüntülemek olsun.

awk '{print $1}' ~/ornek.txt

Elde edeceğimiz sonuç şu şekilde olacaktır.

Ad
Ad
Ali
Burcu

Murat
30
Ayşe

Ad ve Soyad bilgilerini beraber yazdırmak istersek mantıken şu şekilde bir kod yazmamız gerekecektir, değil mi?

awk '{print $1 $2}' ~/ornek.txt

Yukarıdaki kodu uyguladığınızda göreceksiniz ki veri Ad ve Soyad değerleri arasında boşluk olmaksızın görüntülenecektir. Bu durumu düzeltmek için string ifade kullanımını belirten çift tırnak (“”) işimize yarayacaktır.

awk '{print $1 " " $2}' ~/ornek.txt

Tüm sütunları görüntülemek için ise şu komutları kullanabiliriz.

awk '{print $0}' ~/ornek.txt
awk '{print}' ~/ornek.txt

Komutlar içerisinde kullanabileceğiniz length, NR ve NF’den bahsetmek gerekirse; length belirtilen satırdaki karakter sayısını, NR satır sayısını, NF ise satırdaki boşlukla ayrılmış alan sayısını verecektir.

awk '{print NF}' ~/ornek.txt

Yukarıdaki kodu uyguladığımızda alacağımız dönüş şu şekilde olacaktır:

5
5
4
0
4
2
5

Yani, verilerimiz 5 sütun altında bulunuyor (ilk sayı başlıkları belirtiyor), ancak son satır dışında alanların tamamının doldurulduğu başka bir satıra sahip değiliz. Hatta, 3 satır tamamen boş. Peki, sütunların başlıklarını biliyoruz ve verileri listelerken başlıklar haricinde veriler bize dönsün istiyoruz. O halde if ile satırl kontrolü (NR) yapıp, ilk satırın es geçilmesini (NR!=1) ve kalanların listelenmesini sağlayabiliriz.

awk '{if (NR!=1) {print}}' ~/ornek.txt

Veri yığını içerisinde sadece tüm alanları doldurulmuş olan satırları görüntülemek istersek:

awk '{if (NF==5) print}' ~/ornek.txt

if kullanımında süslü parantez kullanımında NR ve NF örneklerinde 2 farklı yazım olduğunu görebilirsiniz.

Hazır if ile standart kullanımın biraz dışına çıktık, o halde bir örnekle değer atama işleminden de bahsetmek istiyorum. Yukarıdaki örnek veri içeriğinde düşünün ki bir nedenden dolayı sütunların yerlerini değiştirmeniz ve son halini yeni bir döküman olarak kayıt etmeniz gerekiyor.

awk Kullanımında Filtreleme ve Matematiksel İşlemler

Elimizde 3 sütundan (Örn. Continent, Country, Population) oluşan bir tablo olsun. Bu tablonun 2. sütununda bulunan bir değeri alıp (Country değeri X olan ülkeler) bu değere ait Population toplamını alalım.

awk -F ';' '$2 ~ /X/ {sum += $3} END {print sum}' workbook.csv

Dosyamızın adı workbook.csv, comma separated olarak sütunların ayrıştırıldığı tabloda ';' ile ayrıştırma için kullandığımız karakteri belirtelim. $2 sütunu ile Country sütununda X değerini aratıp {sum += $3} ile değerlerin toplamını döndürebiliriz.

Continent Country Population
A X 23123
B W 123123121
C X 2421
D Q 45657
E W 2346
F X 30987
G Q 5436
H X 234
I Q 246
J W 89724
K X 2348
L Q 50123
M X 1734
N Q 2137
O W 99542
P X 67523
R W 9654
S X 215469
T Q 78932
U W 23862
V X 1694
Y W 98717
Z Q 3257

Yukarıdaki kod ve tabloyu baz aldığımızda komutun döndüreceği sonuç 345533 olacaktır.

awk Kullanımında Özel Karakterler

\n Yatayda yeni satır. \t Tab karakteri. \v Dikeyde satır. \” Çift tırnak. Çift tırnak işareti string belirteci olarak kullanıldığı için verinin string olarak algılanmamasını çift tırnak işaretinin önüne \ koyarak sağlayabilirsiniz. Örneklerde ilişkili olarak sınırlandırdığım bu özel karakterler2 dışında, elbette kullanabileceğiniz farklı özellikli karakterler de mevcut.

İçeriği Düzenlemek

Örnekleri biraz daha geliştirerek devam edelim ve bir sonraki örneğimizi sütun sıralaması üzerine gerçekleştirelim.

awk '{ print $1 $2 $3 $5 $4 }' ~/ornek.txt > yeni.txt

Yukarıdaki kod sütun sıralamasını değiştirip (5 ve 4’ü yer değiştirerek) oluşan yeni çıktıyı yeni.txt dosyasına aktaracaktır. Ancak yukarıdaki örneklerde görmüştük ki bu işlem neticesinde sütunlar arasındaki boşluk da ortadan kalkacaktır. Bu durumda çift tırnak işaretiyle aralara boşluklar atabilir, virgüller sütunları sıralayabilir ya da var olan sırayı bir değişkene atayabiliriz.

awk '{ print $1 " " $2 " " $3 " " $5 " " $4 }' ~/ornek.txt > yeni.txt
awk '{ print $1,$2,$3,$5,$4 }' ~/ornek.txt > yeni.txt
awk '{age = $3; $3 = ""; print $0, age; }' ~/ornek.txt > yeni.txt

Sütunlarla sıralamasıyla ilgili basit değişikliklerin ardından sütunlar arası ile ilgili düzenlemelerle devam edelim.

awk '"} {print--BEGIN {OFS="- $1,$2,$3,$5,$4}' ~/ornek.txt > yeni.txt

Yukarıdaki komutla hem sütunların sıralamasını değiştirmiş hem de sütunlar arasındaki boşluğu “—” ile değiştirmiş ve düzenlenmiş bu veriyi de yeni.txt dökümanı olarak kayıt etmiş olacağız.

ls | awk -F"." '/JPG/{print "mv "$1"."$2" "$1".doc"}' | bash

Yukarıdaki kod ise bulunulan dizindeki dosyalar listelenip içeriğinde uzantısı JPG olan dosyaların isim ve uzantı bilgileri isim ve *.doc olarak düzenlenecektir. Yani, JPG dosyalar aynı isimle DOC olarak kayıt edilecektir. Kod içerisindeki -F”.” sütun ayırıcı karakterin boşluk yerine nokta . olacağını belirtmektedir. Sonraki bash ise elde edilen çıktının komut olarak işlenmesini sağlayacaktır. Hazır sütun ayraçlarını detaylandırmışken space-separated dosyalar yerine tab-separated3 (tsv) ve comma-separated4 (csv) separated verilerle ilgili de birkaç örnekle devam edebiliriz. Örnek veri olarak NGDC/WDS Global Historical Tsunami Database sayfasındaki tsunami runup data5 işimize yarayacaktır.

cat tsevent.txt | awk -F"\t" '{print $15, $16}'
awk -F"\t" '{if (NR!=1) {print "https://www.google.com.tr/maps/@" $15 "," $16 ",15z"}}' tsevent.txt > gmaps.txt

Yukarıdaki komut kullanım örnekleri sonucunda tsunami runup data veri yığını içerisinde enlem ve boylamlarını Google Maps6 linkleri olarak elde edeceğiz. Google haritalar linklendirmesini hariç tutarsak aşağıdaki komutlar da yine tab-separated veriler için kullanılabilir.

awk 'BEGIN {FS="\t"; ORS="\n"}; {print $15, $16}' tsevent.txt

csv-separated dökümanlarda ise \t alan ifadelerini virgül ile değiştirmemiz yeterli olacaktır.

awk 'BEGIN {FS=","; ORS="\n"}; {print $15, $16}' tsevent.txt

AWK Script Kullanımı

Yukarıda bahsi geçen tüm komutları bir awk script olarak tutabilir ve -f opsiyonu ile çağırarak veri düzenleme işlemlerinizde kullanabilirsiniz. Örnek bir kullanım olarak aşağıdaki komutu inceleyebilirsiniz. AWK Dosyası (islem.awk)

BEGIN {FS=":" ; OFS="-" ; ORS="\n#\n"} { print "No " NR ":\t" $1,$3} END {print "Total: " NR}

awk dili ile ilgili man awk komutunun yanı sıra, çok daha kapsamlı örnekler için enderunix.org > awk programlama , linuxconfig.org > Learning Linux Commands: awk, grymoire.com > AWK sayfalarını inceleyebilirsiniz.