---
title: 'Alan Tabanlı İşleme'
source: 'https://academia.sh/tr/kurslar/kabuk-programlama/alan-tabanli-isleme'
course: 'Kabuk Programlama'
language: tr
updated: '2026-08-17T18:10:03+00:00'
license: 'CC BY-SA 4.0'
---

# Alan Tabanlı İşleme

Kayıt ve alan modeli, kalıp–eylem yapısı, yerleşik değişkenler, ilişkisel dizilerle birikim ve tek geçişte rapor üretimi.

Akış editörü satırı bir metin olarak görür; alanları ancak kalıpla taklit edebilir.
Kütükteki dokuzuncu alanı almak için satırın tamamını betimleyen bir kalıp yazmak
gerekmişti ve o kalıp, biçim küçük bir değişikliğe uğradığında bozulur.

Sütunlu veri için ayrı bir araç sınıfı vardır. **Alan tabanlı işleme aracı**, girdiyi
kayıtlara, kayıtları alanlara böler ve kalıp–eylem çiftlerinden oluşan bir program
yürütür. Bu ders o modeli kurar ve önceki konuda ilişkisel dizilerle yazılan sayımları
tek satıra indirir.

## Kayıt ve Alan Modeli

Girdi öntanımlı olarak satırlara — **kayıtlara** — bölünür. Her kayıt, boşluk kümelerine
göre **alanlara** ayrılır. `$1` birinci alanı, `$0` kaydın tamamını, `$NF` son alanı
verir.

```sh
head -2 erisim.log | awk '{ print NR, NF, $1, $9, $NF }'
```

```
1 10 10.0.0.12 200 5120
2 10 10.0.0.31 200 2048
```

Yerleşik değişkenler modelin çevresini tamamlar:

| Değişken | İçerik |
|---|---|
| `NR` | okunan kayıt sayısı (dosyalar boyunca birikir) |
| `FNR` | o dosyadaki kayıt sırası |
| `NF` | o kayıttaki alan sayısı |
| `FS` | alan ayırıcısı (öntanımlı: boşluk kümeleri) |
| `OFS` | çıktı alan ayırıcısı (öntanımlı: tek boşluk) |
| `FILENAME` | okunmakta olan dosyanın adı |

Öntanımlı ayırıcının "boşluk kümeleri" olması önemlidir: art arda gelen boşluklar tek
ayırıcı sayılır ve satır başındaki boşluklar yok sayılır. Bu, `cut` komutundan ayrıldığı
noktadır — `cut` her ayırıcıyı ayrı sayar ve hizalanmış metinlerde boş alanlar üretir.

## Kalıp ve Eylem

Program, `kalıp { eylem }` çiftlerinden oluşur. Kayıt kalıba uyuyorsa eylem çalışır.

```sh
awk '$9 >= 500 { print $1, $7, $9 }' erisim.log
```

```
192.168.1.5 /api/veri 500
192.168.1.5 /api/veri 500
10.0.2.7 /api/veri 500
```

İki bölüm de isteğe bağlıdır ve eksik olan yerine varsayılan konur:

- Kalıp yazılmazsa eylem **her kayda** uygulanır.
- Eylem yazılmazsa varsayılan eylem `{ print }` olur.

```sh
awk '$9 == 404' erisim.log | grep -c ''
```

```
4
```

Kalıp bir düzenli ifade de olabilir. `/kalıp/` tüm kaydı, `$9 ~ /kalıp/` belirli bir alanı
sınar:

```sh
awk '$9 ~ /^[45]/ { n++ } END { print n }' erisim.log
```

Programın tamamı **tek tırnak içinde** yazılır. Programda `$` işareti alan başvurusudur;
çift tırnak kullanılırsa kabuk onu değişken genişletmesi sanar ve program bozulur. Bu,
Değişkenler ve Tırnak Kuralları dersindeki kuralın en sık gerekli olduğu yerdir.

## `BEGIN` ve `END`

`BEGIN` bloğu ilk kayıt okunmadan, `END` bloğu son kayıttan sonra çalışır. Başlık yazmak,
ayar yapmak ve birikimleri raporlamak için kullanılır.

```sh
awk '
  BEGIN { print "adres            bayt" }
  { t += $10 }
  END { printf "toplam: %d bayt, %d istek, ortalama %.1f\n", t, NR, t / NR }
' erisim.log
```

```
adres            bayt
toplam: 117780 bayt, 30 istek, ortalama 3926.0
```

Değişkenler bildirilmeden kullanılır; ilk kullanımda sayısal bağlamda sıfır, dizgi
bağlamında boş dizi değerindedirler. `t += $10` satırı bu yüzden ayrı bir ilklendirme
gerektirmedi.

`printf` biçimlendirmesi, kabuğun `printf` komutuyla aynı belirteçleri kullanır ve
ondalıklı sayı basabilir — kabuk aritmetiğinin tam sayı kısıtı burada yoktur.

## İlişkisel Diziler

Diziler yalnızca ilişkiseldir ve bildirim gerektirmez. Anahtar başına sayım, önceki
konudaki kabuk döngüsünün tek satırlık karşılığıdır:

```sh
awk '{ sayim[$7]++ } END { for (y in sayim) printf "%3d %s\n", sayim[y], y }' erisim.log \
  | sort -rn | head -5
```

```
  6 /api/veri
  4 /yok.html
  4 /index.html
  3 /urun/45
  3 /urun/12
```

Anahtar başına toplam da aynı desendir:

```sh
awk '{ bayt[$7] += $10 } END { for (y in bayt) printf "%8d %s\n", bayt[y], y }' erisim.log \
  | sort -rn | head -5
```

```
   36120 /panel
   25230 /urun/12
   21990 /urun/45
   20480 /index.html
    7236 /api/veri
```

`for (anahtar in dizi)` döngüsünün ürettiği sıra tanımsızdır; sıralı çıktı için dışarıdan
`sort` gerekir. Bu, ilişkisel dizilerin karma tablosuyla gerçekleştirilmesinin doğrudan
sonucudur ve Veri Yapıları kursunda tanımlanmıştı.

## Alan Ayırıcısını Değiştirmek

`-F` seçeneği alan ayırıcısını belirler. Değer tek karakter ya da düzenli ifade olabilir.

```sh
printf 'a:b:c\nd:e:f\n' | awk -F: '{ print $2 }'
```

```
b
e
```

Çıktı ayırıcısı ayrı bir değişkendir:

```sh
head -2 erisim.log | awk 'BEGIN { OFS="|" } { print $1, $7, $9 }'
```

```
10.0.0.12|/index.html|200
10.0.0.31|/statik/stil.css|200
```

`print` komutunda alanlar **virgülle** ayrılır; virgül `OFS` ile yer değiştirir. Virgül
yerine boşluk yazılırsa alanlar ayırıcısız bitiştirilir — bu, dizgi birleştirmenin
yazımıdır ve sessiz bir hata kaynağıdır.

Bir alana atama yapmak kaydı yeniden kurar:

```sh
head -1 erisim.log | awk '{ $1="GIZLI"; print }' | cut -c1-45
```

```
GIZLI - - [07/Feb/2024:09:12:44 +0000] "GET /
```

Kayıt yeniden kurulurken alanlar `OFS` ile birleştirilir; özgün satırdaki çoklu boşluklar
korunmaz. Alan gizleme ve maskeleme işlemlerinde beklenen davranış budur.

## Sayı ve Dizgi Bağlamı

Alanlar hem sayı hem dizgi olarak yorumlanabilir; hangi yorumun uygulanacağı işlecin
türüne ve işlenenlerin kaynağına bağlıdır. Girdiden gelen bir alan sayı gibi görünüyorsa
sayısal karşılaştırılır; ancak dizgi sabitleriyle karşılaştırıldığında dizgi bağlamı
kazanabilir.

```sh
awk 'BEGIN { x="10"; y="9"; print (x   > y  ) ? "dizgi: 10>9" : "dizgi: 10<9" }'
awk 'BEGIN { x="10"; y="9"; print (x+0 > y+0) ? "sayi: 10>9"  : "sayi: 10<9"  }'
```

```
dizgi: 10<9
sayi: 10>9
```

Belirsizliği ortadan kaldırmanın yolu bağlamı açıkça zorlamaktır: sayısal karşılaştırma
için `+0`, dizgi karşılaştırması için `""` ile birleştirme. Dış kaynaklı veriyle çalışan
programlarda bu alışkanlık, açıklaması güç sonuçları önler.

## Kabuk Değişkeni Aktarmak

Kabuk değişkenleri program metnine gömülmez; `-v` seçeneğiyle aktarılır.

```sh
esik=400
awk -v esik="$esik" '$9 >= esik { n++ } END { print n " istek " esik " ve uzeri" }' erisim.log
```

```
9 istek 400 ve uzeri
```

Değeri program metnine gömmek — tırnakları kapatıp açarak — iki nedenle yanlıştır:
değerdeki tırnak ve ters bölü karakterleri programı bozar, ve dışarıdan gelen bir değer
program kodu hâline gelerek istenmeyen komutlar çalıştırabilir. `-v` bu sınırı korur.

## Bozuk Kayıtları Yakalamak

Alan sayısı, biçim doğrulamasının en ucuz ölçütüdür:

```sh
awk 'NF != 10 { print FILENAME ":" FNR ": alan sayisi " NF }' tumu.log
```

```
tumu.log:31: alan sayisi 2
tumu.log:32: alan sayisi 9
```

Düzenli İfadeler dersinde aynı iş satırın tamamını betimleyen bir kalıpla yapılmıştı.
Alan sayısı sınaması daha dar bir doğrulama yapar ama çok daha kısa yazılır ve biçim
değişikliklerine dayanıklıdır. İkisi birlikte kullanılabilir: alan sayısı hızlı eleme,
kalıp ayrıntılı doğrulama içindir.

## Çok Kalıplı Program

Programda birden çok kalıp–eylem çifti bulunabilir; her kayıt tüm çiftlere karşı sırayla
sınanır.

```sh
awk '
  $9 ~ /^2/     { basarili++ }
  $9 ~ /^[45]/  { hata++; hatali_yol[$7]++ }
  END {
    printf "basarili=%d hata=%d\n", basarili, hata
    for (y in hatali_yol) printf "  %-14s %d\n", y, hatali_yol[y]
  }
' erisim.log | sort
```

```
  /api/veri      3
  /gizli         2
  /yok.html      4
basarili=18 hata=9
```

Bir kayıt birden çok kalıba uyuyorsa ilgili tüm eylemler çalışır; `case` yapısındaki "ilk
eşleşen dal" kuralı burada geçerli değildir.

## Betiğe Uygulama

`rapor.sh` şu ana dek her sayım için kütüğü baştan okuyordu: satır sayımı, bayt toplamı ve
dört durum sınıfı için altı ayrı geçiş. Hepsi tek geçişe iner:

```sh
kutuk=erisim.log

awk -v adet="$adet" '
  { istek++; bayt += $10; yol[$7]++; sinif[substr($9, 1, 1)]++ }
  END {
    printf "istek   : %d\n", istek
    printf "bayt    : %d\n", bayt
    printf "ortalama: %.1f bayt\n", (istek ? bayt / istek : 0)
    print ""
    print "durum kodu siniflari:"
    for (s = 2; s <= 5; s++)
      printf "  %sxx %4d  %%%.1f\n", s, sinif[s], (istek ? sinif[s] * 100 / istek : 0)
  }
' "$kutuk"
```

```
istek   : 30
bayt    : 117780
ortalama: 3926.0 bayt

durum kodu siniflari:
  2xx   18  %60.0
  3xx    3  %10.0
  4xx    6  %20.0
  5xx    3  %10.0
```

Üç kazanç var. Kütük bir kez okunuyor. Yüzdeler ondalıklı ve ölçeklendirme hilesi
gerekmiyor. Sıfıra bölme koruması, kabuktaki üçlü işleçle aynı biçimde yazılıyor.

Kayıp da var: rapor mantığının bir bölümü artık kabukta değil, gömülü bir programda.
Betiğin okunurluğu, bu programın kısa ve tek amaçlı kalmasına bağlıdır. İki yüz satırlık
gömülü programlar, kabuk betiğinin sınırının aşıldığının işaretidir.

## Özet

- Girdi kayıtlara, kayıtlar alanlara bölünür; `$0` kaydın tamamı, `NF` alan sayısı,
  `NR` kayıt sırasıdır. Öntanımlı ayırıcı boşluk kümeleridir.
- Program `kalıp { eylem }` çiftlerinden oluşur; kalıp yoksa her kayda, eylem yoksa
  `print` uygulanır ve kayıt tüm çiftlere karşı sınanır.
- `BEGIN` ve `END` blokları kayıt akışının dışında çalışır; değişkenler bildirimsizdir ve
  sıfırdan başlar.
- İlişkisel dizilerle anahtar başına sayım ve toplam tek satırda yazılır; gezinme sırası
  tanımsızdır.
- Kabuk değerleri program metnine gömülmez, `-v` ile aktarılır.
- Sayı ve dizgi bağlamı işlenenlere bağlıdır; `+0` ve `""` ile açıkça zorlanır.

## Sonraki Adım

Sayımlar üretildi ama sıralanmaları hep dış bir komuta bırakıldı. Sonraki ders o komutu ve
yanındaki iki aracı ele alır: anahtara göre sıralama, komşu yinelemeleri tekilleştirme ve
iki sıralı akışı küme işlemleriyle karşılaştırma — ayrıca sıralamanın yerel ayara bağlı
olmasının betiklerde neden bir hata kaynağı olduğunu.
