awk komutu: Alan yazdırma, -F ayırıcısı ve koşul kalıplarının kullanımı
awk komutu, bir metin dosyasını satır satır okuyan, boşluklara veya belirttiğiniz ayırıcıya göre alanlara bölen ve yalnızca koşula uyan satırların alanlarını seçip yazdıran ya da hesaplayan bir Linux aracıdır. Bir AlmaLinux 9 sunucusunda, örnek web sunucusu erişim günlüğü dosyasındaki IP başına istek sayısını ve durum kodu başına adedi sort ile pipe üzerinden birleştirilen tek satırlık komutla topladığımızda, on iki satırdaki üç 404 yanıtının hepsinin aynı IP'den gelen wp-login.php ve .env istekleri olduğunu gördük.
Aşağıdaki çıktı, AlmaLinux 9.8 sunucusunda root hesabıyla bir çalışma klasörü içinde alınmıştır. Erişim günlüğü, hesap listesi, satış kayıtları ve puan dosyası test için hazırlanmış örnek dosyalardır; içlerindeki IP adresleri ve hesap adları da örnek değerlerdir.
1️⃣ awk komutunun temel kullanımı
awk okuduğu satırı boşluklara göre böler ve alanlara baştan itibaren $1, $2, $3 gibi numaralar verir. Bunu ad, sonuç ve puanın boşlukla ayrıldığı scores.txt ile doğruladık.
cat scores.txtalice pass 82
bob fail 47
carol pass 91
dave pass 68
erin fail 55Tek tırnak içindeki süslü parantezler her satırda çalışacak eylemi tutar; print'ten sonra alan numaralarını virgülle sıralarsanız yalnızca o alanlar çıkar. Birinci ve üçüncü alanı yazdırınca yalnızca ad ve puan kalır.
awk '{print $1, $3}' scores.txtalice 82
bob 47
carol 91
dave 68
erin 55Alanlar arasındaki virgülü kaldırıp $1 $3 yazarsanız iki değer boşluksuz birleşir. print'teki virgül çıktı ayırıcısını (varsayılan olarak bir boşluk) ekler, virgülsüz yan yana yazılan değerler ise tek bir dizeye birleşir.
awk '{print $1 $3}' scores.txtalice82
bob47
carol91
dave68
erin55NR şimdiye kadar okunan satırın numarası, NF ise o satırdaki alan sayısıdır. $NF son alanı ifade eder, bu yüzden alan sayısı satırdan satıra değişse de son sütunu seçebilirsiniz.
awk '{print NR, NF, $NF}' scores.txt1 3 82
2 3 47
3 3 91
4 3 68
5 3 55Web sunucusu erişim günlüğü de boşluklarla ayrıldığı için alanları aynı şekilde seçersiniz. Test erişim günlüğünün ilk satırındaki alan numaraları aşağıdaki gibidir.
| Alan | İlk satırdaki değer | Anlamı |
|---|---|---|
| $1 | 192.0.2.10 | İstemci IP'si |
| $4 | [29/Oct/2026:00:01:12 | İstek tarihi ve saati |
| $6 | "GET | İstek yöntemi (önünde çift tırnak bulunur) |
| $7 | /index.html | İstek adresi |
| $9 | 200 | Durum kodu |
| $10 | 5120 | Gönderilen bayt |
| $11 | "-" | Önceki sayfa (Referer) |
| $12~$15 | "Mozilla/5.0 (X11; Linux x86_64)" | Kullanıcı aracısı (her boşlukta bölünür) |
İstemci IP'si, istek adresi ve durum koduna karşılık gelen $1, $7 ve $9'u seçip yazdırdık.
awk '{print $1, $7, $9}' access.log192.0.2.10 /index.html 200
198.51.100.7 /about.html 200
192.0.2.10 /images/logo.png 200
203.0.113.25 /wp-login.php 404
203.0.113.25 /wp-login.php 404
192.0.2.10 /contact.html 200
198.51.100.7 /old-page.html 301
203.0.113.25 /.env 404
192.0.2.44 /index.html 200
198.51.100.7 /api/search?q=awk 500
192.0.2.44 /images/logo.png 304
192.0.2.10 /index.html 200Kullanıcı aracısı gibi değerinde boşluk bulunan sütunlar birkaç alana bölünür. İlk üç satırın hepsinde NF 15 idi ve $NF, kullanıcı aracısının son parçasıdır.
awk '{print NF, $NF}' access.log | head -315 x86_64)"
15 x86_64)"
15 x86_64)"2️⃣ awk -F ile ayırıcı belirleme
Sütunları boşluk dışında bir işaretle ayrılmış dosyalarda -F'den sonra o işareti yazarsınız. /etc/passwd ile aynı biçimde hazırlanan hesap listesi users.txt'te -F olmadan $1 yazdırınca çoğu satır olduğu gibi çıktı.
awk '{print $1}' users.txtroot:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
nobody:x:65534:65534:Kernel
user:x:1000:1000:Example
deploy:x:1001:1001:Deploy
backup:x:1002:1002::/home/backup:/sbin/nologinVarsayılan ayırıcı boşluk olduğu için yalnızca iki noktayla bağlanan satırda tek alan vardır. Açıklama sütununda boşluk bulunan nobody, user ve deploy satırları yalnızca o boşlukta kesilir.
-F: ile iki noktayı ayırıcı yaparsanız hesap adı ($1) ve oturum açma kabuğu ($7) ayrılır.
awk -F: '{print $1, $7}' users.txtroot /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
nobody /sbin/nologin
user /bin/bash
deploy /bin/bash
backup /sbin/nologinVirgülle ayrılmış CSV dosyalarını -F, ile bölersiniz. Satış kayıtları sales.csv'deki ürün ve miktarı yazdırınca ilk satırdaki başlık (item qty) da aynı şekilde bölünüp birlikte çıkar.
awk -F, '{print $2, $3}' sales.csvitem qty
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2-F, çift tırnaklı sütunların içinde virgül bulunan CSV dosyalarına uygun değildir. Ürün sütununda virgül bulunan quoted.csv'de alanlar tırnak içindeki virgüllerde de bölünür ve ikinci alanda ürün adının yalnızca ilk kısmı kalır.
awk -F, '{print $2}' quoted.csvitem
"cable
keyboardGNU Awk, bu tür dosyalar için FPAT değişkeninin kullanımını resmî kılavuzunda açıklar. Ayırıcı yerine bir alanın biçimini düzenli ifadeyle yazarsanız tırnaklı sütun tek alan olarak çıkar.
awk -v FPAT='([^,]*)|("[^"]*")' '{print $2}' quoted.csvitem
"cable, usb"
keyboardBirden çok ayırıcı kullanmak için köşeli parantez içinde düzenli ifade yazın. İki nokta ve eğik çizgiyi birlikte ayırıcı yaparsanız $NF, oturum açma kabuğu yolunun son adı (bash, nologin) olur.
awk -F'[:/]' '{print $1, $NF}' users.txtroot bash
bin nologin
daemon nologin
nobody nologin
user bash
deploy bash
backup nologin3️⃣ awk komutunda koşul kalıpları
Alan seçseniz de tüm satırlar yazdırılır; yalnızca gereken satırları bırakmak için süslü parantezden önce bir koşul (kalıp) koyun. Eğik çizgiler arasına yazdığınız dize yalnızca onu içeren satırları seçer, eylemi yazmazsanız satırın tamamı çıkar.
awk '/wp-login/' access.log203.0.113.25 - - [29/Oct/2026:00:04:51 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"
203.0.113.25 - - [29/Oct/2026:00:04:52 +0000] "POST /wp-login.php HTTP/1.1" 404 196 "-" "Mozilla/5.0 (X11; Linux x86_64)"Satır seçme sonucu grep komutu ile aynıdır, awk ise seçtiği satırlardan alanları da doğrudan seçip yazdırır. grep ile seçilen aynı iki satırı pipe ile awk'a aktarırsanız yalnızca IP ve durum kodu kalır.
grep wp-login access.log | awk '{print $1, $9}'203.0.113.25 404
203.0.113.25 404Alan değerlerini ==, !=, >, >=, <, <= ile karşılaştırırsınız. Durum kodu ($9) 404 olan satırları seçip IP ve istek adresini yazdırdık.
awk '$9 == 404 {print $1, $7}' access.log203.0.113.25 /wp-login.php
203.0.113.25 /wp-login.php
203.0.113.25 /.envBir dizeyle karşılaştırırken değeri çift tırnağa alın. İkinci alanı pass olan adları seçtik.
awk '$2 == "pass" {print $1}' scores.txtalice
carol
daveSayısal karşılaştırma, hesap numarası (UID) gibi aralıkla seçim yaparken kullanılır. UID'si 1000 ve üzeri olan hesapları seçerseniz normal hesaplarla birlikte UID'si 65534 olan nobody de gelir.
awk -F: '$3 >= 1000 {print $1, $3}' users.txtnobody 65534
user 1000
deploy 1001
backup 1002İki koşulu && ile birleştirirsiniz. 65534'ten küçük koşulunu eklerseniz nobody çıkar, yalnızca üç normal hesap ve ev klasörleri kalır.
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $6}' users.txtuser /home/user
deploy /home/deploy
backup /home/backup[~] alanın düzenli ifadeyle eşleşip eşleşmediğini, [!~] eşleşmediğini denetler. Oturum açma kabuğu ($7) bash ile biten hesapları ve nologin olmayan hesapları ayrı ayrı seçince aynı üç hesap çıkar.
awk -F: '$7 ~ /bash$/ {print $1}' users.txtroot
user
deployawk -F: '$7 !~ /nologin/ {print $1, $7}' users.txtroot /bin/bash
user /bin/bash
deploy /bin/bashNR koşulu satır numarasına göre seçer. NR > 1 ile CSV'nin başlık satırını çıkarırsanız yalnızca satış kayıtları kalır.
awk -F, 'NR > 1 {print $2, $3}' sales.csvkeyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2Başka komutların çıktısını da pipe ile aktarıp aynı şekilde bölersiniz. ls -l çıktısından dosya boyutunu ($5) ve adını ($9) seçince ilk satır boş çıktı, çünkü ls -l'nin ilk satırı [total 24] beşinci ve dokuzuncu alanlara sahip değildir.
ls -l | awk '{print $5, $9}'
1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txtNR > 1 eklerseniz ilk satır çıkar, yalnızca dosya boyutları ve adları kalır.
ls -l | awk 'NR > 1 {print $5, $9}'1567 access.log
79 quoted.csv
207 sales.csv
85 scores-copy.txt
85 scores.txt
315 users.txt4️⃣ awk BEGIN, END, toplam ve ortalama
BEGIN bloğu ilk satır okunmadan önce bir kez, END bloğu son satır işlendikten sonra bir kez çalışır. Toplam için her satırda bir değişkene ekler, END'de yazdırırsınız. Aşağıdaki şema, satış kayıtlarındaki tutarların toplamını bulurken awk'ın her satırda izlediği sırayı gösterir.
$ awk -F, 'NR > 1 {t += $3 * $4} END {printf "total %.2f\n", t}' sales.csvErişim günlüğündeki gönderilen baytların ($10) toplamı 41298 bayt oldu. İlk kez kullanılan değişken boş değerle (sayı olarak 0) başlar, bu yüzden ayrıca 0 vermeniz gerekmez.
awk '{sum += $10} END {print sum}' access.log41298Toplamı END yerine her satırda çalışan eylemde yazdırırsanız, her satır okunduğunda o ana kadarki toplam çıkar. Miktar ile birim fiyat çarpımını t'ye her eklediğinizde satır numarası ve t'yi yazdırırsanız başlık hariç yedi satır çıkar ve son satırdaki 886.3 genel toplamdır.
awk -F, 'NR > 1 {t += $3 * $4; print NR, t}' sales.csv2 90
3 189.5
4 378.5
5 423.5
6 468.5
7 508.3
8 886.3Ortalamayı END'de toplamı satır sayısına bölerek bulursunuz. Beş puanın toplamı 343, ortalaması 68.6 idi.
awk '{total += $3; n++} END {print total, n, total / n}' scores.txt343 5 68.6BEGIN, sonuçların üstüne bir kez başlık satırı yazdırmak için kullanılır. Ürün ve tutarların (miktar × birim fiyat) üstünde item total satırı yalnızca bir kez çıkar.
awk -F, 'BEGIN {print "item", "total"} NR > 1 {print $2, $3 * $4}' sales.csvitem total
keyboard 90
mouse 99.5
monitor 189
keyboard 45
cable 45
mouse 39.8
monitor 378Çıktı ayırıcısını BEGIN'de OFS değişkeniyle değiştirirsiniz. OFS'yi virgül yaparsanız print'teki virgüllerin yerine boşluk değil virgül gelir ve hesap listesi CSV biçiminde çıkar.
awk 'BEGIN {FS = ":"; OFS = ","} {print $1, $3, $7}' users.txtroot,0,/bin/bash
bin,1,/sbin/nologin
daemon,2,/sbin/nologin
nobody,65534,/sbin/nologin
user,1000,/bin/bash
deploy,1001,/bin/bash
backup,1002,/sbin/nologinSütunları hizalamak için printf kullanın. %-10s 10 karakterlik sola hizalı dize, %3d 3 karakterlik tam sayı, %8.2f ise iki ondalıkla 8 karaktere sığdırılmış sayıdır.
awk -F, 'NR > 1 {printf "%-10s %8.2f\n", $2, $3, $3 * $4}' sales.csvkeyboard 2 90.00
mouse 5 99.50
monitor 1 189.00
keyboard 1 45.00
cable 10 45.00
mouse 2 39.80
monitor 2 378.00printf, print'in aksine satır atlamaz, bu yüzden biçimin sonuna [\n] yazın. [\n] olmadan çalıştırırsanız ürün adları tek satırda birleşir.
awk -F, 'NR > 1 {printf "%s ", $2}' sales.csvkeyboard mouse monitor keyboard cable mouse monitor5️⃣ awk komutuyla günlük analizi ve seçenekler
🔲 Günlük analizi
Tek bir değişkene eklemek yalnızca tek toplam verir; istemci IP'sine veya durum koduna göre ayrı saymak için değerleri bir dizide toplayın. n[$1]++, IP'yi anahtar alan dizi elemanına 1 ekler, END'deki for (ip in n) ise toplanan elemanları tek tek çıkarır.
awk '{n[$1]++} END {for (ip in n) print n[ip], ip}' access.log | sort -rn4 192.0.2.10
3 203.0.113.25
3 198.51.100.7
2 192.0.2.44for (ip in n) döngüsünün sırası belirli değildir (GNU Awk kılavuzuna göre), bu yüzden sort -rn ile istek sayısına göre sıraladık. 192.0.2.10, 4 istekle en yüksekti.
Durum kodu başına adedi de aynı şekilde sayarsınız. 3 adet 404 ve 1 adet 500 yanıtı vardı.
awk '{n[$9]++} END {for (s in n) print s, n[s]}' access.log | sort200 6
301 1
304 1
404 3
500 1Yalnızca durum kodlarını çıkarıp sort ve uniq -c'ye aktarmak da aynı sayıları verir.
awk '{print $9}' access.log | sort | uniq -c 6 200
1 301
1 304
3 404
1 500Yalnızca hata yanıtlarını görmek için durum koduna koşul koyun. 400 ve üzeri satırlar, wp-login.php ve .env arayan üç istek ile bir 500 hatasıydı.
awk '$9 >= 400 {print $9, $1, $7}' access.log404 203.0.113.25 /wp-login.php
404 203.0.113.25 /wp-login.php
404 203.0.113.25 /.env
500 198.51.100.7 /api/search?q=awkIP başına gönderilen bayt toplamını da bir diziye ekleyerek bulursunuz. 192.0.2.10, 31340 baytla en çok alan oldu.
awk '{b[$1] += $10} END {for (ip in b) print b[ip], ip}' access.log | sort -rn31340 192.0.2.10
5120 192.0.2.44
4250 198.51.100.7
588 203.0.113.25Saat alanı ($4) dize olarak karşılaştırılabilir. Tarihi ve biçimi aynı satırlarda dize sırası saat sırasıyla aynı olduğundan yalnızca 00:05 ile 00:10 öncesi arasındaki dört isteği seçtik.
awk '$4 >= "[29/Oct/2026:00:05" && $4 < "[29/Oct/2026:00:10" {print $4, $7}' access.log[29/Oct/2026:00:05:30 /contact.html
[29/Oct/2026:00:07:02 /old-page.html
[29/Oct/2026:00:07:15 /.env
[29/Oct/2026:00:09:48 /index.html🔲 awk komutu seçenekleri
📌 Başlıca seçenekler: bu yazıda çalıştırılan sonuçlar
| Seçenek | Görev | Bu yazıdaki sonuç |
|---|---|---|
| -F fs | Giriş alanı ayırıcısını belirler | -F: users.txt'te hesap adı ($1) ve oturum açma kabuğunu ($7) ayırır, -F, sales.csv'deki ürün ve miktarı başlıkla (item qty) birlikte verir |
| -v var=val | Program çalışmadan önce değişkene değer atar | min kabuk değişkenini -v min=$min ile aktarınca gönderilen baytı 1000 ve üzeri olan altı satır çıkar, -v FPAT=… ile quoted.csv'deki tırnaklı sütun tek alan olur |
| -i inplace | Çıktıyı ekran yerine özgün dosyaya kaydeder | gawk -i inplace çalıştırıldıktan sonra ekranda hiçbir şey çıkmaz ve scores.txt kopyası ad ve puandan oluşan iki sütuna düşer, -v inplace::suffix=.bak eklenirse önceki içerik .bak dosyasında kalır |
| --version | Sürüm bilgisini yazdırır | [awk --version] ilk satırı GNU Awk 5 sürümünü gösterir |
📎 Diğer seçenekler: resmî kılavuza göre
| Seçenek | Görev |
|---|---|
| -f program-file | AWK programını ilk komut satırı bağımsız değişkeni yerine dosyadan okur, -f birden çok kez verilebilir |
| -e program-text | Komut satırına yazılan metni AWK program kaynağı olarak kullanır, -f veya --include ile yüklenen kitaplık işlevleriyle birlikte kullanılabilir |
| -E file | -f'ye benzer ama en son işlenir ve komut satırı değişken atamalarını engeller, #! betikleri içindir |
| --traditional | Uyumluluk kipinde çalışır, GNU uzantılarını tanımaz |
| --posix | Uyumluluk kipini açar ve ek kısıtlamalar getirir, örneğin function'ın eş anlamlısı func'u tanımaz |
| --lint | Şüpheli veya başka AWK uygulamalarına taşınması zor yapıları uyarır, --lint=fatal ile uyarılar ölümcül hataya dönüşür |
| --dump-variables | Genel değişkenlerin türünü ve son değerini sıralı bir liste olarak dosyaya yazar, dosya belirtilmezse awkvars.out |
🔲 awk komutu simülatörü
Aşağıdaki simülatörde aynı test dosyaları üzerinde awk komutlarını kendiniz girebilirsiniz.
🔢 SSS & önerilen içerikler
Sıralama
Linux sort komutu: Dosya sıralama
Dosya içeriğini alfabetik veya sayısal olarak sıralayan sort komutu. awk toplamlarını büyükten küçüğe görmek için ardından kullanılır.
Yinelenenleri kaldırma
Linux uniq komutu
Art arda gelen aynı satırları teke indiren ve -c ile kaç kez tekrarlandığını sayan uniq komutu.
Dosya görüntüleme
Linux head komutu ve tail komutu
Dosyanın yalnızca ilk veya son birkaç satırını gösteren head ve tail komutları. Sunucunun erişim günlüğünü kontrol ederken sık kullanılır.
ℹ️ Satış ortaklığı bildirimi
Bu sitenin içeriklerinde satış ortaklığı bağlantıları bulunur. Bir ziyaretçi bu bağlantılar üzerinden ürün veya hizmet satın alırsa bu site satıcıdan komisyon alır. Bu süreçte alıcının ödediği tutar (kampanya indirimlerinde tutar düşer↓) artmaz. Yayımlanan fiyat, indirim ve stok bilgileri yazının yazıldığı zamana aittir ve gerçek durumdan farklı olabilir; bu yüzden satın almadan önce son bilgiyi satıcıdan kontrol etmenizi rica ederiz. Ürünler kendi ölçütlerimize göre seçilir ve değerlendirilir; komisyon alınıp alınmaması tanıtım sırasını veya değerlendirme içeriğini etkilemez.