wc Komutu ile Dosya ve Metin İstatistikleri Çıkarma

Yıllarca log dosyalarıyla boğuşan biri olarak şunu rahatlıkla söyleyebilirim: wc komutu, görünürde basit ama doğru kullanıldığında inanılmaz işler yapan araçlardan biri. “Satır sayısı mı lazım? wc -l yaz geç” diye geçiştirilen bu komut, aslında günlük sysadmin hayatının tam ortasında duruyor. Log analizi, script yazımı, dosya doğrulama, pipeline işlemleri… Hepsinde wc bir şekilde sahne alıyor.

wc Nedir, Ne Yapar?

wc, “word count” kelimesinin kısaltması. Ama adına bakıp sadece kelime sayar diye düşünmek hata olur. Temel olarak üç şeyi sayar: satır, kelime ve byte/karakter. Bu üç bilgiyle birlikte dosya hakkında hızlı bir istatistiksel özet çıkarabilirsiniz.

Sözdizimi son derece sade:

wc [seçenekler] [dosya...]

Temel parametreler şunlar:

  • -l: Sadece satır sayısını gösterir
  • -w: Sadece kelime sayısını gösterir
  • -c: Byte sayısını gösterir
  • -m: Karakter sayısını gösterir (multibyte karakterlerde -c’den farklı sonuç verir)
  • -L: En uzun satırın karakter uzunluğunu gösterir

Hiç parametre vermezseniz, wc size sırasıyla satır, kelime ve byte sayısını verir:

wc /etc/passwd

Çıktı şuna benzer bir şey olur:

  45  91 2534 /etc/passwd

45 satır, 91 kelime, 2534 byte. Tek komutla. Fazla söze gerek yok.

Temel Kullanım Örnekleri

Satır Sayımı: -l Seçeneği

Log yönetiminde en sık kullandığım seçenek bu. Bir log dosyasında kaç satır var, ne kadar büyümüş, dün gece kaç event üretilmiş gibi sorulara anında cevap veriyor:

# Nginx access log kaç satır?
wc -l /var/log/nginx/access.log

# Birden fazla dosyayı aynı anda say
wc -l /var/log/nginx/*.log

# Sadece sayıyı al, dosya adını değil (script için ideal)
wc -l < /var/log/nginx/access.log

Son kullanım önemlı. wc -l dosya.log yazdığınızda çıktıya dosya adı da eklenir. Ama wc -l < dosya.log yazdığınızda sadece sayıyı alırsınız. Script yazarken bu farkı göz ardı ederseniz string karşılaştırmalarınız patlar.

Kelime Sayımı: -w Seçeneği

Kelime sayımı, konfigürasyon dosyası doğrulaması veya metin analizi gerektiren durumlarda işe yarıyor:

# Bir config dosyasındaki kelime sayısı
wc -w /etc/nginx/nginx.conf

# Pipe ile kullanım - grep çıktısını say
grep "ERROR" /var/log/app.log | wc -w

Byte ve Karakter Sayımı

# Dosya boyutunu byte cinsinden öğren
wc -c /var/log/syslog

# Türkçe veya özel karakterler varsa -m daha doğru sonuç verir
wc -m rapor.txt

# En uzun satırı bul - config dosyalarında çok işe yarar
wc -L /etc/ssh/sshd_config

-c ve -m arasındaki farka dikkat etmek gerekiyor. ASCII karakterlerden oluşan dosyalarda aynı sonucu verirler. Ama Türkçe karakterler, emoji veya başka multibyte karakterler varsa -m size gerçek karakter sayısını, -c ise byte sayısını verir. Türkçe bir “ş” harfi UTF-8’de 2 byte yer kaplar mesela.

Gerçek Dünya Senaryoları

Senaryo 1: Log Rotasyonu Öncesi Kontrol

Üretim ortamında log rotasyonu yapmadan önce mevcut durumu anlamak istiyorsunuz. Sadece ls -la ile boyuta bakmak yeterli değil, kaç satır olduğunu, ortalama satır uzunluğunu da bilmek istiyorsunuz:

#!/bin/bash
# log_stats.sh - Log dosyası istatistikleri

LOG_FILE="/var/log/nginx/access.log"

LINES=$(wc -l < "$LOG_FILE")
WORDS=$(wc -w < "$LOG_FILE")
BYTES=$(wc -c < "$LOG_FILE")
MAX_LINE=$(wc -L < "$LOG_FILE")

echo "=== Log Dosyası İstatistikleri ==="
echo "Dosya: $LOG_FILE"
echo "Toplam satır: $LINES"
echo "Toplam kelime: $WORDS"
echo "Boyut (byte): $BYTES"
echo "En uzun satır: $MAX_LINE karakter"

if [ "$LINES" -gt 100000 ]; then
    echo "UYARI: Log dosyası 100K satırı geçti, rotasyon önerilir!"
fi

Bu script’i cron’a ekleyip sabah 8’de mail ile kendinize gönderirseniz, güne log durumunu bilerek başlarsınız.

Senaryo 2: Hata Sayısı Takibi

Uygulama loglarında belirli hata tiplerinin ne kadar sıklıkla göründüğünü takip etmek için grep ve wc ikilisi biçilmiş kaftan:

# Son 1 saatteki ERROR kayıtları
grep "ERROR" /var/log/app/application.log | wc -l

# Belirli bir IP'nin kaç istek attığını bul
grep "192.168.1.100" /var/log/nginx/access.log | wc -l

# 500 status code kaç kez döndü?
grep " 500 " /var/log/nginx/access.log | wc -l

# Birden fazla kriterin kombinasyonu
grep "ERROR" /var/log/app/application.log | grep "database" | wc -l

Bu tür kullanımları bir monitoring script’ine dönüştürdüğünüzde, Zabbix veya Prometheus ile entegre olmayan sistemlerde bile basit bir alert mekanizması kurabilirsiniz.

Senaryo 3: Çoklu Dosya Analizi ve Toplam

Birden fazla log dosyasını aynı anda analiz etmek ve toplam almak:

# Tüm nginx loglarının özeti
wc -l /var/log/nginx/*.log

# Çıktı şuna benzer:
#   1523 /var/log/nginx/access.log
#    234 /var/log/nginx/error.log
#   8901 /var/log/nginx/access.log.1
#  10658 total

# Sadece toplamı almak için
wc -l /var/log/nginx/*.log | tail -1

# Ya da awk ile sadece toplam sayıyı çek
wc -l /var/log/nginx/*.log | awk '/total/{print $1}'

wc birden fazla dosya aldığında otomatik olarak total satırı ekliyor. Bu çok kullanışlı ama bazen sadece o sayıyı almak istiyorsunuz, tail -1 veya awk kombinasyonu burada devreye giriyor.

Senaryo 4: Script Çıktısı Doğrulama

Bir script’in ürettiği çıktıyı doğrulamak için wc sık kullanılır. Mesela bir veritabanı yedeği aldınız, içinde gerçekten kayıt var mı diye kontrol etmek istiyorsunuz:

#!/bin/bash
# backup_verify.sh

BACKUP_FILE="/backup/mysql_dump_$(date +%Y%m%d).sql"

# Yedek oluştur
mysqldump -u root -p mydb > "$BACKUP_FILE"

# Satır sayısını kontrol et
LINE_COUNT=$(wc -l < "$BACKUP_FILE")

echo "Yedek dosyası: $BACKUP_FILE"
echo "Satır sayısı: $LINE_COUNT"

# Minimum satır sayısı kontrolü (boş dump mı?)
if [ "$LINE_COUNT" -lt 50 ]; then
    echo "HATA: Yedek dosyası şüpheli derecede küçük!"
    echo "Manuel kontrol gerekli."
    exit 1
fi

echo "Yedek doğrulaması başarılı."

Bu yaklaşım profesyonel bir doğrulama mekanizması değil elbette, ama hızlı bir sanity check olarak işe yarıyor. Gerçek doğrulama için mysqlcheck kullanırsınız tabii.

Senaryo 5: Kod Tabanı İstatistikleri

Yazılım geliştirme süreçlerinde ekibin ürettiği kod miktarını veya proje büyüklüğünü hızlıca ölçmek için:

# Tüm Python dosyalarının toplam satır sayısı
find /opt/myapp -name "*.py" | xargs wc -l

# Sadece toplamı al
find /opt/myapp -name "*.py" | xargs wc -l | tail -1

# Belirli bir dizindeki tüm script'ler
find /usr/local/bin -type f | xargs wc -l 2>/dev/null | sort -n

# Boş satırları hariç tut (biraz daha karmaşık ama işe yarar)
grep -v "^$" /opt/myapp/main.py | wc -l

Son komut ilginç: önce grep -v "^$" ile boş satırları filtreliyoruz, sonra wc -l ile gerçek kod satırlarını sayıyoruz. Code review süreçlerinde “bu dosyada 500 satır kod var” demek yerine boş satırlar hariç gerçek satır sayısını vermek daha anlamlı.

Pipeline’da wc Kullanımı

wc komutunun asıl gücü pipeline içinde ortaya çıkıyor. Tek başına kullandığınızda faydalı, ama diğer komutlarla birleştirdiğinizde vazgeçilmez hale geliyor.

# Kaç tane unique IP adresi var?
awk '{print $1}' /var/log/nginx/access.log | sort | uniq | wc -l

# Sistemde kaç aktif kullanıcı var?
who | wc -l

# Kaç process çalışıyor?
ps aux | wc -l

# /etc dizininde kaç config dosyası var?
find /etc -name "*.conf" -type f | wc -l

# Cron job'ların toplam sayısı
crontab -l 2>/dev/null | grep -v "^#" | grep -v "^$" | wc -l

Bu komutların hepsini ezberlemek zorunda değilsiniz. Mantığı anladığınızda, herhangi bir durumda wc -l‘yi nereye koyacağınızı kendiniz buluyorsunuz.

Gelişmiş Kullanım: Here String ve Process Substitution

Standart örneklerin ötesine geçelim biraz:

# Here string ile
wc -w <<< "Bu bir test cümlesidir"
# Çıktı: 4

# Değişkenin içeriğini analiz et
METIN="sistemde bir sorun var acil müdahale gerekiyor"
echo "Kelime sayısı: $(wc -w <<< "$METIN")"

# Process substitution ile
wc -l <(grep "ERROR" /var/log/app.log)

# Birden fazla komut çıktısını karşılaştır
diff <(wc -l /etc/hosts) <(wc -l /etc/hostname)

Here string (<<<) özellikle script yazarken çok kullanışlı. Geçici dosya oluşturmadan bir string üzerinde wc çalıştırmanıza olanak tanıyor.

Karakter Kodlaması Tuzakları

Daha önce -c ve -m farkından bahsettim ama bu konuyu biraz daha açmak istiyorum çünkü Türkçe sistemlerde beklenmedik sonuçlarla karşılaşabilirsiniz:

# Türkçe karakter içeren dosya
echo "Şişli'de şişe şişiriyorum" > test_turkce.txt

# Byte sayısı (Türkçe karakterler 2 byte)
wc -c test_turkce.txt

# Gerçek karakter sayısı
wc -m test_turkce.txt

# Locale'i göster
locale

# Locale'i değiştirip tekrar dene
LC_ALL=C wc -m test_turkce.txt  # Yanlış sonuç verecek
LC_ALL=tr_TR.UTF-8 wc -m test_turkce.txt  # Doğru sonuç

Özellikle cron job’larda veya farklı kullanıcı ortamlarında çalışan script’lerde locale ayarı önemli. Script başında export LC_ALL=tr_TR.UTF-8 veya export LANG=tr_TR.UTF-8 eklemek iyi bir pratik.

Pratik Monitoring Senaryosu

Bütün bu bilgileri bir araya getirerek gerçekten kullanılabilir bir script yapalım:

#!/bin/bash
# simple_log_monitor.sh
# Cron ile her 5 dakikada çalıştırın:
# */5 * * * * /usr/local/bin/simple_log_monitor.sh

APP_LOG="/var/log/myapp/application.log"
THRESHOLD_ERROR=50
THRESHOLD_WARN=100
ALERT_EMAIL="[email protected]"

# Son 5 dakikanın loglarını al (basit yaklaşım)
RECENT_LINES=$(tail -1000 "$APP_LOG")

# Hata sayılarını hesapla
ERROR_COUNT=$(echo "$RECENT_LINES" | grep -c "ERROR")
WARN_COUNT=$(echo "$RECENT_LINES" | grep -c "WARN")
TOTAL_LINES=$(wc -l < "$APP_LOG")

# Sonuçları logla
echo "$(date): ERROR=$ERROR_COUNT, WARN=$WARN_COUNT, TOTAL=$TOTAL_LINES" >> /var/log/monitor.log

# Threshold kontrolü
if [ "$ERROR_COUNT" -gt "$THRESHOLD_ERROR" ]; then
    echo "KRITIK: Son kontrol periyodunda $ERROR_COUNT ERROR bulundu!" | 
    mail -s "LOG ALERT: Kritik Hata Seviyesi" "$ALERT_EMAIL"
fi

Bu basit görünebilir ama production’da düzgün çalışıyor. Karmaşık monitoring sistemleri kuramadığınız, hızlı bir çözüm gerektiği durumlarda hayat kurtarıyor.

Performans Notu

Büyük dosyalarda wc beklenenden yavaş çalışabilir. 10GB’lık bir log dosyasında wc -l çalıştırdığınızda bir süre beklemeniz gerekecek. Bu durumda birkaç alternatif yaklaşım var:

# Büyük dosyalarda yaklaşık satır sayısı (hızlı ama kesin değil)
# İlk 1MB'ı örnekle, toplam boyuta göre tahmin et
SAMPLE_LINES=$(head -c 1M /var/log/büyük.log | wc -l)
FILE_SIZE=$(wc -c < /var/log/büyük.log)
APPROX_LINES=$((SAMPLE_LINES * FILE_SIZE / 1048576))
echo "Yaklaşık satır sayısı: $APPROX_LINES"

# Ya da awk kullan, bazen daha hızlı
awk 'END{print NR}' /var/log/büyük.log

Gerçi modern disklerde ve yeterli RAM’de wc oldukça hızlı. 1GB’lık dosyayı genellikle 2-3 saniyede işler. Ama 50GB’lık archive loglarında bu yaklaşım işinize yarayabilir.

Sık Yapılan Hatalar

Yeni başlayanların ve zaman zaman deneyimlilerin bile düştüğü bazı tuzaklar var:

  • Dosya adının çıktıya eklenmesi: wc -l dosya.txt yerine wc -l < dosya.txt kullanmak, özellikle script’lerde sayıyı integer olarak işlemek istediğinizde kritik.
  • Boşluk karakterleri: wc -l‘nin saydığı şey newline karakterleri. Son satırda newline yoksa o satır sayılmaz. Bazı araçların ürettiği dosyalarda bu sorun çıkabilir.
  • Binary dosyalar: Binary dosyalarda wc anlamsız sonuçlar verebilir. Önce file komutuyla dosya tipini kontrol etmek mantıklı.
  • Pipe ile satır sayısı: cat dosya.txt | wc -l çalışır ama gereksiz cat kullanımıdır. Direkt wc -l dosya.txt veya wc -l < dosya.txt tercih edin.

Sonuç

wc komutu, Linux araç kutusunun en mütevazı ama en güvenilir üyelerinden. Tek başına bile pratik olmakla birlikte, asıl değeri grep, awk, sort, uniq gibi komutlarla pipeline içinde kullandığınızda ortaya çıkıyor. Log analizi, script doğrulama, sistem monitoring, kod istatistikleri… Tüm bu alanlarda temel bir yapı taşı görevi görüyor.

Pratik tavsiyem şu: bir dahaki log analizinde veya script yazımında, saymak istediğiniz bir şeyle karşılaştığınızda ilk aklınıza gelen komut wc olsun. Büyük ihtimalle doğru araçla karşı karşıyasınız. Geri kalanını pipeline halleder.

Bir yanıt yazın

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