awk komutu: Alan yazdırma, -F ayırıcısı ve koşul kalıplarının kullanımı

Test ortamıRHEL ailesiAlmaLinux 9.8root hesabı2026-10-29 tarihinde kontrol edildi

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ı

  • ↪️ Alan numaraları ve print

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.txt
alice   pass  82
bob     fail  47
carol   pass  91
dave    pass  68
erin    fail  55

Tek 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.txt
alice 82
bob 47
carol 91
dave 68
erin 55

Alanlar 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.txt
alice82
bob47
carol91
dave68
erin55

NR ş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.txt
1 3 82
2 3 47
3 3 91
4 3 68
5 3 55

Web 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ğerAnlamı
$1192.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
$9200Durum kodu
$105120Gö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.log
192.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 200

Kullanı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 -3
15 x86_64)"
15 x86_64)"
15 x86_64)"

2️⃣ awk -F ile ayırıcı belirleme

  • ↪️ İki nokta, virgül ve düzenli ifade ayırıcıları

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.txt
root: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/nologin

Varsayı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.txt
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
nobody /sbin/nologin
user /bin/bash
deploy /bin/bash
backup /sbin/nologin

Virgü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.csv
item 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.csv
item
"cable
keyboard

GNU 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.csv
item
"cable, usb"
keyboard

Birden ç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.txt
root bash
bin nologin
daemon nologin
nobody nologin
user bash
deploy bash
backup nologin

3️⃣ awk komutunda koşul kalıpları

  • ↪️ Düzenli ifadeler, karşılaştırma ve NR

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.log
203.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 404

Alan 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.log
203.0.113.25 /wp-login.php
203.0.113.25 /wp-login.php
203.0.113.25 /.env

Bir 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.txt
alice
carol
dave

Sayı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.txt
nobody 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.txt
user /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.txt
root
user
deploy
awk -F: '$7 !~ /nologin/ {print $1, $7}' users.txt
root /bin/bash
user /bin/bash
deploy /bin/bash

NR 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.csv
keyboard 2
mouse 5
monitor 1
keyboard 1
cable 10
mouse 2
monitor 2

Baş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.txt

NR > 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.txt

4️⃣ awk BEGIN, END, toplam ve ortalama

  • ↪️ Değişkenler ve printf çıktı biçimleri

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'ın sales.csv'yi satır satır işleme sırası
Açıklama diyagramı
🔁 İşleme sırası
$ awk -F, 'NR > 1 {t += $3 * $4} END {printf "total %.2f\n", t}' sales.csv
① Okunan satırNR = 1date,item,qty,priceNR = 22026-10-01,keyboard,2,45.00NR = 32026-10-01,mouse,5,19.90NR = 82026-10-04,monitor,2,189.00Okunacak satır kalmadı8. satır son satırdır.
② Alanlara bölme (-F,)$1date$2item$3qty$4priceBaşlık satırı da aynı şekilde bölünür.$12026-10-01$2keyboard$32$445.00$3 miktar, $4 birim fiyat$12026-10-01$2mouse$35$419.90$3 miktar, $4 birim fiyat$12026-10-04$2monitor$32$4189.00$3 miktar, $4 birim fiyatBölünecek satır yokEND bloğu satır okumaz.
③ Kalıp ve eylemNR > 1 yanlışEylem atlanır.t = (boş)NR > 1 doğrut += 2 * 45.00t = 90NR > 1 doğrut += 5 * 19.90t = 189.5NR > 1 doğrut += 2 * 189.00t = 886.3END çalışırtotal 886.30printf, t'yi iki ondalık basamakla yazdırır.
İlk satır başlık satırı olduğu için NR > 1 yanlış olur ve awk eylemi çalıştırmadan sonraki satıra geçer.
İkinci satırdan itibaren kalıp doğru olur; miktar ile birim fiyatın çarpımı olan 90, t değişkenine eklenir.
t değişkeni satır değişse de değerini korur, bu yüzden üçüncü satıra kadarki toplam 189.5'tir.
4-7. satırlar da aynı sırayla işlenir ve son 8. satıra kadarki t 886.3 olur.
Son satır işlendikten sonra END bloğu bir kez çalışır ve printf total 886.30 yazdırır.

Eriş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.log
41298

Toplamı 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.csv
2 90
3 189.5
4 378.5
5 423.5
6 468.5
7 508.3
8 886.3

Ortalamayı 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.txt
343 5 68.6

BEGIN, 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.csv
item 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.txt
root,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/nologin

Sü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.csv
keyboard     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.00

printf, 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.csv
keyboard mouse monitor keyboard cable mouse monitor

5️⃣ awk komutuyla günlük analizi ve seçenekler

  • ↪️ İstemci IP'si ve durum kodu sayımı, seçeneklerin özeti

🔲 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 -rn
4 192.0.2.10
3 203.0.113.25
3 198.51.100.7
2 192.0.2.44

for (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 | sort
200 6
301 1
304 1
404 3
500 1

Yalnı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 500

Yalnı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.log
404 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=awk

IP 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 -rn
31340 192.0.2.10
5120 192.0.2.44
4250 198.51.100.7
588 203.0.113.25

Saat 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çenekGörevBu yazıdaki sonuç
-F fsGiriş 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=valProgram çalışmadan önce değişkene değer atarmin 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 kaydedergawk -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
--versionSü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çenekGörev
-f program-fileAWK programını ilk komut satırı bağımsız değişkeni yerine dosyadan okur, -f birden çok kez verilebilir
-e program-textKomut 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
--traditionalUyumluluk kipinde çalışır, GNU uzantılarını tanımaz
--posixUyumluluk 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-variablesGenel 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.

awk komutu simülatörüGNU Awk 5
[root@server work]#
Yalnızca tarayıcınızda çalışan küçük bir awk yorumlayıcısıdır. Dört test dosyası ölçümlerde kullanılan dosyalarla aynıdır, önceki komutları ↑↓ ile geri çağırırsınız.

🔢 SSS & önerilen içerikler

Tek tırnak içindeki $min kabuk tarafından değiştirilmez ve awk'a olduğu gibi gider, bu yüzden -v seçeneğiyle aktarın. min kabuk değişkenine 1000 verip -v min=$min ile aktarırsanız gönderilen baytı 1000 ve üzeri olan altı satır çıkar. awk programını çift tırnağa alırsanız kabuk [print $1] içindeki $1'i bile önce boş değerle değiştirir ve satırın tamamı yazdırılır.

GNU Awk, -i inplace eklenince çıktıyı ekran yerine özgün dosyaya kaydeder. scores.txt kopyasında birinci ve üçüncü alanı yazdıran programı gawk -i inplace ile çalıştırınca ekranda hiçbir şey çıkmadı ve dosya ad ve puandan oluşan iki sütuna düştü. Özgün dosyanın üzerine doğrudan yazıldığı için -v inplace::suffix=.bak eklerseniz önceki içerik .bak dosyasında kalır.

AlmaLinux 9 sunucusunda /usr/bin/awk, gawk'ı gösteren sembolik bir bağlantıydı ve [awk --version] ilk satırı GNU Awk 5 sürümünü gösteriyordu. Bu sunucuda iki ad aynı programı çalıştırır. -i inplace veya FPAT gibi GNU Awk özelliklerini kullanmadan önce [awk --version] ile GNU Awk olduğunu doğrulayın.

ℹ️ 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.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İnsan olduğunuzu kanıtlayın: 7   +   10   =