awk Komutu ve Kullanımı
awk
, grep
ve sed
'e benzer şekilde, örüntü temelli tarama ve işleme dilidir.
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.
- Vivek Gite. (2017). How To Use awk In Bash Scripting ↩
- Aaron Kili. (2016). How to Use Awk and Regular Expressions to Filter Text or String in Files ↩
- Tab separated values. DataTables ↩
- Comma Separated Values (CSV) Standard File Format. edoceo ↩
- NGDC/WDS Global Historical Tsunami Database. NOAA ↩
- Ceyhun Enki Aksan. (2017). Coğrafi Koordinat Sistemi Nedir? ↩