grep ile Metin Arama: Temel ve İleri Kullanım

Sistem yöneticiliğinde geçirdiğim yıllar boyunca, bir sorun çıktığında ilk refleksim hep aynı oldu: terminale geç, grep yaz. Log dosyaları karışmış mı? grep. Bir config dosyasında bir satırı mı arıyorsun? grep. Yüzlerce dosya arasında belirli bir string mi bulmak istiyorsun? Yine grep. Bu komut, Linux dünyasının İsviçre çakısı gibi bir şey ve onu iyi bilmek, sysadmin hayatını gerçekten kolaylaştırıyor. Bu yazıda temel kullanımdan başlayıp ileri seviye tekniklere kadar, gerçek dünya senaryolarıyla grep‘i ele alacağız.

grep Nedir ve Nasıl Çalışır?

grep, “Global Regular Expression Print” kelimelerinin kısaltmasıdır. İsminden de anlaşılacağı üzere, düzenli ifadeler (regular expressions) kullanarak metin içinde arama yapan bir araçtır. 1973 yılında Ken Thompson tarafından yazılmış, o günden bu yana Unix/Linux dünyasının vazgeçilmez parçası haline gelmiştir.

Temel mantığı şudur: verilen bir deseni, verilen giriş metninde satır satır arar ve eşleşen satırları ekrana basar. Basit görünüyor değil mi? Ama bu basit mantığın üzerine inanılmaz derecede güçlü kullanım senaryoları inşa edebilirsiniz.

Temel sözdizimi şöyledir:

grep [seçenekler] "aranacak_desen" dosya_adı

Temel grep Kullanımı

Hemen işe koyulalım. En basit kullanım senaryosuyla başlayalım: bir dosyada belirli bir kelimeyi aramak.

# /etc/passwd dosyasında "nginx" kullanıcısını ara
grep "nginx" /etc/passwd

# Bir log dosyasında "error" kelimesini ara
grep "error" /var/log/syslog

# Büyük/küçük harf farkı gözetmeden ara (-i parametresi)
grep -i "error" /var/log/syslog

Bu kadar basit bir komutla bile işe yarayan sonuçlar elde edebiliyorsunuz. Ama grep‘in asıl gücü, zengin parametre seçeneklerinde yatıyor.

Temel Parametreler

-i: Büyük/küçük harf duyarsız arama yapar. “Error”, “ERROR”, “error” hepsini bulur.

-v: Eşleşmeyen satırları gösterir. Yani tersine arama yapar.

-n: Eşleşen satırın satır numarasını gösterir.

-c: Eşleşen satır sayısını gösterir, satırları değil.

-l: Sadece eşleşme bulunan dosyaların adlarını gösterir.

-L: Eşleşme bulunmayan dosyaların adlarını gösterir.

-w: Tam kelime eşleşmesi arar. “error” aradığında “errors” veya “terror” çıkmaz.

-x: Satır tam eşleşmesi arar. Tüm satır desenle örtüşmeli.

-r veya -R: Dizinleri özyinelemeli (recursive) olarak tarar.

-A [n]: Eşleşen satırdan sonra n satır daha gösterir (After).

-B [n]: Eşleşen satırdan önce n satır gösterir (Before).

-C [n]: Eşleşen satırın öncesinde ve sonrasında n satır gösterir (Context).

-E: Genişletilmiş düzenli ifadeler kullanır (egrep ile aynı).

-P: Perl uyumlu düzenli ifadeler kullanır.

-o: Sadece eşleşen kısmı gösterir, tüm satırı değil.

–color: Eşleşen kısımları renklendirir (çoğu sistemde varsayılan olarak açık gelir).

Gerçek Dünya Senaryoları: Log Analizi

Sysadmin hayatının büyük bölümü log okumakla geçer. grep bu işi inanılmaz ölçüde kolaylaştırır.

# Nginx access log'unda 500 hata kodlarını bul
grep " 500 " /var/log/nginx/access.log

# Son 1 saatin loglarında kritik hataları bul (tarih formatına göre)
grep "$(date '+%d/%b/%Y:%H')" /var/log/nginx/access.log | grep " 500 "

# Birden fazla log dosyasında aynı anda ara
grep -r "CRITICAL" /var/log/

# Satır numarasıyla birlikte göster, sonra vim'de direkt o satıra gidebilirsin
grep -n "segfault" /var/log/kern.log

Bir üretim sunucusunda bir servis çöktüğünde, ilk yapacağım şey genellikle şu komuttur:

# Son 50 satıra bak, öncesinde ve sonrasında 5 satır context ile
grep -n "error|failed|critical" /var/log/syslog | tail -50

# Belirli bir IP adresinden gelen tüm istekleri bul
grep "192.168.1.100" /var/log/nginx/access.log

# O IP'nin 404 aldığı sayfaları filtrele
grep "192.168.1.100" /var/log/nginx/access.log | grep " 404 "

Bağlam parametreleri (-A, -B, -C) özellikle değerlidir. Bir hata satırı buldunuz, ama o hatanın öncesinde ne olduğunu görmek istiyorsunuz:

# "Out of memory" hatasından önceki 10 satırı da göster
grep -B 10 "Out of memory" /var/log/kern.log

# SSH başarısız giriş denemelerini çevresiyle göster
grep -C 3 "Failed password" /var/log/auth.log

Düzenli İfadelerle grep

grep‘in gerçek gücü, düzenli ifadelerle ortaya çıkar. Temel düzenli ifade karakterlerini hatırlayalım:

. (nokta): Herhangi bir tek karakteri temsil eder.

*: Önceki karakterin sıfır veya daha fazla tekrarını temsil eder.

^: Satır başını temsil eder.

$: Satır sonunu temsil eder.

[ ]: Karakter sınıfı tanımlar. [abc] a, b veya c karakterlerinden birini eşleştirir.

[^ ]: Karakter sınıfının tersini alır.

+: Önceki karakterin bir veya daha fazla tekrarı (genişletilmiş regex ile).

?: Önceki karakter sıfır veya bir kez tekrar (genişletilmiş regex ile).

|: VEYA operatörü (genişletilmiş regex ile).

# Satır başında "root" ile başlayan satırları bul
grep "^root" /etc/passwd

# Boş satırları bul
grep "^$" config.txt

# Boş satırları hariç tut
grep -v "^$" config.txt

# # ile başlayan yorum satırlarını hariç tut
grep -v "^#" /etc/ssh/sshd_config

# Hem boş satırları hem yorum satırlarını hariç tut
grep -v "^#|^$" /etc/ssh/sshd_config

Bu son komut aslında çok kullanışlı bir pratik. Bir config dosyasını incelerken yorum satırları ve boş satırlar olmadan bakmak istiyorsunuz, işte tam olarak bu işi yapıyor.

Genişletilmiş Düzenli İfadeler (-E / egrep)

Standart grep bazı özel karakterler için ters bölü işareti () kullanmayı gerektirir. -E parametresi veya egrep komutu, daha okunabilir genişletilmiş düzenli ifadelere olanak tanır:

# Birden fazla desen ara (OR mantığı)
grep -E "error|warning|critical" /var/log/syslog

# IP adresi formatını yakala (basit versiyon)
grep -E "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" /var/log/nginx/access.log

# Port numarası içeren satırları bul
grep -E ":[0-9]{2,5}" /etc/services | head -20

# Belirli uzunlukta kelimeleri bul
grep -E "b[a-zA-Z]{8,}b" dosya.txt

Özyinelemeli Arama: Dizinleri Taramak

Birden fazla dosya veya dizin içinde arama yapmak gerektiğinde -r parametresi devreye girer:

# Tüm Apache config dosyalarında "VirtualHost" ara
grep -r "VirtualHost" /etc/apache2/

# Sadece .conf uzantılı dosyalarda ara
grep -r "ServerName" /etc/apache2/ --include="*.conf"

# .log dosyalarını hariç tut
grep -r "database" /var/www/html/ --exclude="*.log"

# Sadece eşleşen dosya adlarını listele
grep -rl "TODO" /var/www/html/

# Kaç dosyada "deprecated" geçtiğini bul
grep -rl "deprecated" /var/www/html/ | wc -l

Bir projede “deprecated” olarak işaretlenmiş fonksiyon çağrılarını bulmak ya da eski bir IP adresine referans veren tüm config dosyalarını tespit etmek için bu yaklaşım mükemmeldir.

grep’i Diğer Komutlarla Birlikte Kullanmak

grep‘in en güçlü taraflarından biri, pipe ile diğer komutlarla zincir oluşturabilmesidir.

# Çalışan processleri filtrele
ps aux | grep "nginx"

# grep'in kendisini hariç tut (klasik sorun çözümü)
ps aux | grep "nginx" | grep -v "grep"

# Açık portları filtrele
netstat -tulpn | grep "LISTEN"
# veya modern alternatif
ss -tulpn | grep "LISTEN"

# Sisteme bağlı olan belirli bir IP'yi bul
ss -tn | grep "192.168.1.50"

# Disk kullanımında belirli bir eşiği geçen bölümleri bul
df -h | grep -E "[8-9][0-9]%|100%"

Bu son komut aslında çok pratik bir monitoring hilesine dönüşebilir. Disk doluluk oranı %80’i geçen bölümleri tespit etmek için güzel bir yöntem.

Cron Job ve Script Yazımında grep

Otomasyonda grep çıkış kodları kritik önem taşır. grep başarılı bir eşleşme bulduğunda 0, bulamadığında 1, bir hata oluştuğunda 2 döndürür. Bu özellik script yazımında şart koşul olarak kullanılabilir:

#!/bin/bash

# Servis çalışıyor mu kontrol et
if ps aux | grep -q "[n]ginx"; then
    echo "Nginx çalışıyor"
else
    echo "Nginx çalışmıyor! Yeniden başlatılıyor..."
    systemctl start nginx
fi

# Log dosyasında kritik hata var mı?
if grep -q "CRITICAL" /var/log/uygulama.log; then
    echo "Kritik hata tespit edildi!" | mail -s "ALARM" [email protected]
fi

Burada küçük ama önemli bir trick var: grep -q "[n]ginx" kullanımında köşeli parantez içine alınan ilk harf, grep komutunun kendisinin process listesinde görünmesini engeller. Çünkü [n]ginx deseni “nginx” ile eşleşir ama “grep nginx” ile eşleşmez.

Gelişmiş Kullanım: -o ve Veri Çıkartma

-o parametresi, tüm satır yerine sadece eşleşen kısmı gösterir. Bu özellik, metinden belirli veri parçacıklarını çıkarmak için çok kullanışlıdır:

# Log dosyasından sadece IP adreslerini çıkart
grep -oE "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" /var/log/nginx/access.log | sort | uniq -c | sort -rn

# En çok istek atan IP'leri bul (ilk 10)
grep -oE "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

# Email adreslerini çıkart
grep -oE "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}" dosya.txt

# HTTP metotlarını listele ve say
grep -oE ""(GET|POST|PUT|DELETE|PATCH)" /var/log/nginx/access.log | sort | uniq -c

Bu tür komutlar, log analizi raporları hazırlarken veya hızlı bir güvenlik denetimi yaparken inanılmaz işe yarar. Bir sunucuya DDoS saldırısı geldiğinden şüphelendiğinizde, yukarıdaki IP çıkartma komutu size anında hangi IP’nin ne kadar istek yaptığını gösterir.

Büyük Dosyalarda Performans İpuçları

Gigabyte’larca log dosyasında grep çalıştırmak bazen yavaşlayabilir. Performansı artırmak için bazı ipuçları:

–mmap: Dosya okuma için mmap kullanır, büyük dosyalarda daha hızlı olabilir.

-F veya fgrep: Sabit string arama yapar, düzenli ifade yorumlaması olmaz. Eğer regex kullanmıyorsanız bu çok daha hızlıdır.

# Sabit string aramada fgrep veya grep -F kullan
grep -F "192.168.1.1" /var/log/nginx/access.log

# Paralel işlem için xargs ile birleştir
find /var/log -name "*.log" | xargs grep -l "error" 2>/dev/null

# zgrep ile sıkıştırılmış dosyalarda ara (arşivlenmiş loglar için)
zgrep "error" /var/log/syslog.2.gz

# Birden fazla sıkıştırılmış dosyada
zgrep "failed" /var/log/auth.log.*.gz

zgrep‘i özellikle vurgulamak istiyorum. Log rotasyonu yapılan sistemlerde eski loglar genellikle gzip ile sıkıştırılmış olur. Bunları açıp aramak yerine doğrudan zgrep kullanmak hem zaman hem disk alanı tasarrufu sağlar.

Pratik Güvenlik Senaryoları

Güvenlik açısından grep birkaç pratik kullanım daha sunar:

# Başarısız SSH giriş denemelerini say
grep "Failed password" /var/log/auth.log | wc -l

# Hangi kullanıcı adlarıyla giriş denenmiş?
grep "Failed password" /var/log/auth.log | grep -oP "(?<=for )[w]+" | sort | uniq -c | sort -rn

# Root olmayan sudo kullanımlarını izle
grep "sudo" /var/log/auth.log | grep -v "root"

# Sistemde yeni oluşturulan kullanıcıları bul
grep "new user" /var/log/auth.log

# Cron job değişikliklerini izle
grep "CRON" /var/log/syslog | grep -v "CMD"

Bu komutları düzenli çalışacak bir monitoring scripti içine koyabilirsiniz. Günlük olarak çalışıp, eşik değerleri aşıldığında e-posta gönderen basit bir güvenlik izleme sistemi oluşturmak için grep yeterlidir.

grep Alternatifleri: Ne Zaman Başka Araç Kullanmalı?

grep her derde deva değil. Bazı durumlarda alternatiflerini bilmek lazım:

ripgrep (rg): Modern ve çok daha hızlı bir alternatif. Varsayılan olarak .gitignore‘u dikkate alır, çok çekirdekli işlemciyi kullanır. Büyük kod tabanlarında grep -r‘ın yerini almaya başladı.

ag (The Silver Searcher): Benzer şekilde hızlı ve akıllı bir arama aracı.

awk: Eğer sadece belirli alanları (column) işlemeniz gerekiyorsa awk daha uygundur.

sed: Bulduğunuz şeyi değiştirmeniz gerekiyorsa sed‘e geçin.

Ama şunu söyleyeyim: her sunucuda grep vardır. ripgrep veya ag olmayabilir. Dolayısıyla grep‘i iyi bilmek, her ortamda çalışabilmeniz demektir.

Alias ve Kısayollar

Sık kullandığım bazı grep alias’larını .bashrc veya .bash_profile dosyanıza ekleyebilirsiniz:

# Renklendirme ve satır numarası varsayılan olsun
alias grep='grep --color=auto'

# Yorum ve boş satır filtrele
alias grepc='grep -v "^#|^$"'

# Büyük/küçük harf duyarsız özyinelemeli arama
alias grepi='grep -ri'

# Log analizi için özel alias
alias logerr='grep -i "error|critical|fatal|exception"'

Sonuç

grep, öğrenmesi kolay ama ustalaşması zaman alan bir araç. Temel kullanımı dakikalar içinde kavrayabilirsiniz, ancak düzenli ifadeleri, parametre kombinasyonlarını ve pipe zincirlerini özümsemek gerçek anlamda verimli kullanmayı mümkün kılar.

Bu yazıda anlattıklarımı özetlemek gerekirse: temel arama için -i, -n, -v parametrelerini öğrenin. Log analizinde -A, -B, -C ile bağlamı görün. Büyük çaplı taramalarda -r ve --include kombinasyonunu kullanın. Veri çıkartmak için -o ile düzenli ifadeleri birleştirin. Script yazarken çıkış kodlarından yararlanın.

Bir sysadmin olarak şunu söyleyebilirim: her gün en az on kez grep kullanıyorum. Bazen tek satırlık basit aramalar, bazen de birden fazla pipe ile oluşturulan karmaşık analizler. Bu aracı ne kadar iyi bilirseniz, sorunları o kadar hızlı teşhis eder ve çözersiniz.

Pratik yapmanın en iyi yolu, gerçek log dosyaları üzerinde denemek. /var/log/syslog, /var/log/auth.log veya /var/log/nginx/access.log dosyaları her zaman hazır birer pratik sahası. Bugün öğrendiğiniz bir grep komutu, yarın saatlik bir sorun giderme sürecini beş dakikaya indirebilir.

Yorum yapın