Sistem yöneticiliğinde günlük işlerin büyük bir kısmı metin içinde bir şeyler aramakla geçer. Log dosyalarında hata bulmak, konfigürasyon dosyalarında belirli parametreleri tespit etmek, kullanıcı listelerinde filtreleme yapmak… Bunların hepsinde grep kullanırsın. Ama grep‘i sadece düz kelime araması için kullanıyorsan, aracın gücünün belki yüzde onunu kullanıyorsun demektir. Regex, yani düzenli ifadeler, grep‘i gerçek anlamda güçlü bir araca dönüştüren şeydir. Bu yazıda regex temellerini grep bağlamında ele alacağız, gerçek dünya senaryolarıyla pekiştireceğiz.
Regex Nedir ve Neden Öğrenmeye Değer?
Regex, metin kalıplarını tanımlamak için kullanılan özel bir sözdizimi sistemidir. “Tam olarak bu kelimeyi bul” yerine “şu karakterlerle başlayan, şu uzunlukta olan ve şurada biten her şeyi bul” gibi ifadeler yazmanı sağlar. Bir kez öğrendiğinde grep, sed, awk, Python, JavaScript ve daha onlarca araçta kullanabilirsin. Yatırımın karşılığını çok hızlı alırsın.
grep ile üç farklı regex modu kullanabilirsin:
- BRE (Basic Regular Expressions): Varsayılan mod,
grepkomutunun standart davranışı - ERE (Extended Regular Expressions):
grep -Eveyaegrepile kullanılır, daha fazla özellik sunar - PCRE (Perl Compatible Regular Expressions):
grep -Pile kullanılır, en gelişmiş regex desteği
Günlük işlerde çoğunlukla ERE modunu tercih ederim çünkü daha temiz bir sözdizimi sunuyor. Ama temel öğrenme için BRE ile başlamak mantıklı.
Temel Regex Karakterleri
Nokta (.) – Herhangi Bir Karakter
Nokta karakteri, yeni satır dışında herhangi bir tek karakteri temsil eder.
# "log" ile başlayıp herhangi bir karakterle devam eden kalıpları bul
grep "log." /var/log/syslog
# 3 karakter uzunluğunda her kelimeyi bul (boşluklar arasında)
grep " ... " dosya.txt
Yıldız (*) – Sıfır veya Daha Fazla Tekrar
Yıldız, kendinden önceki karakterin sıfır veya daha fazla kez tekrar ettiğini belirtir.
# "error" veya "errorrr" gibi ifadeleri bul
grep "erro*r" /var/log/apache2/error.log
# "ab", "abb", "abbb" gibi kalıpları yakala
grep "ab*" access.log
Dikkat: * tek başına “herhangi bir şey” demez, önceki karakterin sıfır veya daha fazla tekrarı demektir. Bu, shell wildcard’larından farklıdır ve yeni başlayanların en çok takıldığı noktalardan biridir.
Şapka (^) ve Dolar ($) – Satır Başı ve Sonu
# Satır başında "ERROR" ile başlayan satırları bul
grep "^ERROR" /var/log/uygulama.log
# Satır sonu ".conf" ile biten satırları bul
grep ".conf$" dosya_listesi.txt
# Hem başlangıç hem bitiş - tam olarak "root" olan satırları bul
grep "^root$" /etc/passwd
Nokta karakterini literal olarak aramak için ters eğik çizgi ile kaçış yapman gerekir (.). Aksi halde regex motoru onu “herhangi bir karakter” olarak yorumlar.
Karakter Sınıfları – []
Köşeli parantezler içinde belirtilen karakterlerden herhangi biri olabilir anlamına gelir.
# Büyük veya küçük "e" ile başlayan "rror" içeren satırlar
grep "[Ee]rror" /var/log/syslog
# Rakam içeren satırları bul
grep "[0-9]" konfigürasyon.conf
# Rakam veya harf içeren satırlar
grep "[a-zA-Z0-9]" dosya.txt
# Başında büyük harf olan satırlar
grep "^[A-Z]" rapor.txt
Köşeli parantez içinde ^ kullanırsan anlam değişir ve “bunlar dışındaki karakterler” anlamına gelir:
# Rakam içermeyen satırları bul
grep "^[^0-9]*$" dosya.txt
grep Parametreleri
Regex örneklerine geçmeden önce, sık kullanılan grep parametrelerini bilmek gerekiyor:
- -i: Büyük/küçük harf farkını gözetme
- -v: Eşleşmeyen satırları göster (tersine çevir)
- -r: Dizinleri özyinelemeli ara
- -l: Sadece eşleşen dosyaların adlarını göster
- -n: Satır numaralarını göster
- -c: Eşleşen satır sayısını göster
- -E: Genişletilmiş regex modunu kullan
- -P: PCRE regex modunu kullan
- -o: Sadece eşleşen kısmı göster, tüm satırı değil
- -A n: Eşleşmeden sonraki n satırı da göster
- -B n: Eşleşmeden önceki n satırı da göster
- -w: Tam kelime eşleşmesi
- –color: Eşleşen kısımları renklendir
Extended Regex ile Daha Güçlü Kalıplar
grep -E kullanarak çok daha esnek ifadeler yazabilirsin.
Artı (+) ve Soru İşareti (?)
# En az bir rakam içeren satırlar (+ işareti: bir veya daha fazla)
grep -E "[0-9]+" /var/log/auth.log
# "colour" veya "color" - u harfi isteğe bağlı (? işareti: sıfır veya bir)
grep -E "colou?r" kelimeler.txt
# HTTP durum kodlarını bul (3 haneli rakam)
grep -E "[0-9]{3}" /var/log/apache2/access.log
Süslü Parantezler {} – Belirli Tekrar Sayısı
# Tam olarak 3 haneli sayılar
grep -E "[0-9]{3}" dosya.txt
# 2 ile 4 arasında tekrar eden 'a' harfi
grep -E "a{2,4}" dosya.txt
# En az 5 karakter uzunluğunda kelimeler
grep -E "[a-z]{5,}" dosya.txt
Pipe (|) – Ya Bu Ya O
# "error" veya "warning" içeren satırlar
grep -E "error|warning|critical" /var/log/syslog
# TCP veya UDP içeren satırlar
grep -E "TCP|UDP" /var/log/firewall.log
Parantezler – Gruplama
# "restart" veya "reboot" içeren satırlar
grep -E "re(start|boot)" /var/log/syslog
# IP adresi kalıbı (basit versiyon)
grep -E "([0-9]{1,3}.){3}[0-9]{1,3}" access.log
Gerçek Dünya Senaryoları
Senaryo 1: Apache/Nginx Log Analizi
Prodüksiyon sunucusunda yoğun trafik var ve hangi IP adreslerinin 404 hatası aldığını bulmak istiyorsun.
# 404 hatası veren tüm satırları bul ve IP adreslerini çıkar
grep -E " 404 " /var/log/apache2/access.log | grep -oE "^[0-9.]+"
# Son 1 saatteki 5xx hatalarını bul
grep -E " 5[0-9]{2} " /var/log/apache2/access.log | tail -100
# Belirli bir IP'nin tüm isteklerini bul
grep -E "^192.168.1.[0-9]+" /var/log/nginx/access.log
# POST isteklerini bul ve kaç tane olduğunu say
grep -c '"POST' /var/log/nginx/access.log
Senaryo 2: SSH Brute Force Tespiti
Sunucuna SSH ile kaba kuvvet saldırısı olup olmadığını kontrol etmek istiyorsun.
# Başarısız SSH giriş denemelerini bul
grep -E "Failed password|Invalid user" /var/log/auth.log
# Hangi kullanıcı adlarıyla deneme yapılmış
grep -oE "invalid user [a-zA-Z0-9_]+" /var/log/auth.log | sort | uniq -c | sort -rn
# Hangi IP'lerden saldırı geliyor
grep "Failed password" /var/log/auth.log | grep -oE "[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}" | sort | uniq -c | sort -rn | head -20
# Belirli bir tarih aralığındaki başarısız girişler
grep -E "^Jan (1[5-9]|2[0-9])" /var/log/auth.log | grep "Failed password"
Senaryo 3: Konfigürasyon Dosyası Yönetimi
Onlarca sunucuda aynı konfigürasyon dosyasını kontrol etmek gerekiyor.
# /etc altındaki tüm .conf dosyalarında "deprecated" ifadesini bul
grep -r "deprecated" /etc/*.conf
# Yorum satırı olmayan aktif konfigürasyonları göster
grep -vE "^#|^$" /etc/nginx/nginx.conf
# Port numarası içeren satırları bul
grep -E "ports+[0-9]+" /etc/ssh/sshd_config
# Belirli bir IP bloğunun izin verildiği yerleri bul
grep -rE "allows+192.168." /etc/nginx/
# Boş olmayan ve yorum olmayan satır sayısını bul
grep -cE "^[^#]" /etc/apache2/apache2.conf
Senaryo 4: Sistem Log Analizi
Bir serviste sorun var ve log dosyasında ne zaman başladığını bulmak istiyorsun.
# Belirli bir zaman aralığındaki hataları bul
grep -E "^2024-01-15 (1[4-8]):" /var/log/uygulama.log | grep -i "error"
# Hata mesajından önceki ve sonraki 5 satırı göster (bağlam için)
grep -A 5 -B 5 "OutOfMemoryError" /var/log/uygulama.log
# Birden fazla servise ait log satırlarını filtrele
grep -E "(nginx|mysql|php-fpm)" /var/log/syslog | grep -i "error"
# Sadece timestamp ve hata mesajını çıkar
grep -oE "^[0-9-]+ [0-9:]+ .*(ERROR|WARN).*" /var/log/uygulama.log
Email ve IP Doğrulama Kalıpları
Sysadmin olarak kullanıcı girdilerini veya log dosyalarını doğrularken bu kalıpları sıkça kullanırsın.
# Basit email adresi kalıbı
grep -E "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}" kullanici_listesi.txt
# IPv4 adresi - daha katı versiyon
grep -P "b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)b" dosya.txt
# MAC adresi bul
grep -E "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}" network.log
# URL kalıbı
grep -E "https?://[a-zA-Z0-9./%-]+" access.log
POSIX Karakter Sınıfları
Daha okunabilir kalıplar için POSIX karakter sınıflarını kullanabilirsin:
- [:alpha:]: Harf karakterleri (a-z, A-Z)
- [:digit:]: Rakamlar (0-9)
- [:alnum:]: Harf ve rakamlar
- [:space:]: Boşluk karakterleri
- [:upper:]: Büyük harfler
- [:lower:]: Küçük harfler
- [:punct:]: Noktalama işaretleri
# Sadece rakam içeren satırlar
grep "^[[:digit:]]*$" dosya.txt
# Büyük harfle başlayan satırlar
grep "^[[:upper:]]" rapor.txt
# Boşluk içeren satırları bul
grep "[[:space:]]" konfigürasyon.txt
# Alfanümerik olmayan karakterleri içeren satırlar
grep "[^[:alnum:][:space:]]" dosya.txt
Performans İpuçları
Büyük log dosyalarında regex araması yaparken performans önemli hale gelir.
# Önce basit string araması yap, sonra regex ile filtrele (daha hızlı)
grep "ERROR" /var/log/büyük_dosya.log | grep -E "^2024-01-15"
# fgrep (sabit string arama) regex gerektirmeyen durumlarda çok daha hızlı
fgrep "exact string" büyük_dosya.log
# Birden fazla pattern yerine tek bir -E kullan
grep -E "error|warning|critical" dosya.log
# Bu, üç ayrı grep pipe'ından çok daha verimlidir
# Büyük dosyalarda --mmap bazen daha hızlı olabilir
grep --mmap -E "kalıp" çok_büyük_dosya.log
Sık Yapılan Hatalar ve Çözümleri
Hata 1: Nokta karakterini kaçırmak
# Yanlış - 192.168.1.1 yerine 192X168Y1Z1 gibi şeyler de eşleşir
grep "192.168.1.1" dosya.txt
# Doğru - noktalı literal arama
grep "192.168.1.1" dosya.txt
Hata 2: Greedy matching
# HTML taglerini bulmak istiyorsun ama çok fazla eşleşiyor
grep -oE "<.*>" sayfa.html # <b>kalın</b> yerine tüm satırı alabilir
# Daha spesifik kalıp kullan
grep -oE "<[^>]+>" sayfa.html
Hata 3: BRE ve ERE farkını unutmak
# BRE'de + ve ? literal karakter, ERE'de özel anlam taşır
grep "a+" dosya.txt # literal "a+" arar
grep -E "a+" dosya.txt # bir veya daha fazla "a" arar
# BRE'de özel karakterleri kaçış ile kullanmak gerekir
grep "a+" dosya.txt # BRE'de bir veya daha fazla "a"
Pratik Tek Satırlık Komutlar
Günlük işlerde zaman kazandıran bazı hazır kalıplar:
# Sistemdeki tüm cron job'larını listele
grep -rE "^s*[^#]" /etc/cron* /var/spool/cron* 2>/dev/null
# Bir dizindeki tüm PHP dosyalarında SQL injection açığı işareti ara
grep -rE "\$_(GET|POST|REQUEST)[" /var/www/html/ --include="*.php"
# Sudoers dosyasında belirli kullanıcıları bul
grep -E "^%?(sudo|wheel|admin)" /etc/sudoers
# Sistemde SUID bit'li dosyaları listele (ls çıktısında)
ls -la /usr/bin/ | grep -E "^...s"
# Network konfigürasyonunda gateway bul
grep -E "GATEWAY|gateway" /etc/network/interfaces /etc/sysconfig/network* 2>/dev/null
# Aktif dinlenen portları bul
ss -tlnp | grep -E ":[0-9]+" | grep -oE ":[0-9]+" | sort -u
Regex’i Öğrenmek için Pratik Yaklaşım
Regex öğrenmek biraz zaman alır ama sistematik yaklaşırsan hızlanırsın. İlk önce temel meta karakterleri ezberle: ., *, ^, $, []. Sonra ERE’ye geç ve +, ?, {}, |, () ekle. Her yeni kavramı gerçek bir log dosyası üzerinde dene.
grep --color=always kullanmak başlangıçta çok yardımcı olur. Regex’in neyi yakaladığını görsel olarak görmek, kalıpları anlamayı kolaylaştırır. Ayrıca [regex101.com](https://regex101.com) gibi siteler online test etmek için kullanışlıdır, ama son sözü her zaman terminalde çalıştırarak ver.
Kendi “regex kütüphaneni” bir dosyada tutmaya başla. Çalışan bir IP adresi kalıbı buldun mu, bir email regex’i yazdın mı? Bunları not al. Zamanla kendi araç kutunu oluşturursun ve aynı problemi tekrar tekrar çözmek zorunda kalmazsın.
Sonuç
grep ve regex, sysadmin araç kutusunun çekirdeğindedir. Log analizinden güvenlik denetimlerine, konfigürasyon yönetiminden veri çıkarmaya kadar her yerde karşına çıkar. Bu yazıda temel meta karakterlerden başlayıp gerçek dünya senaryolarına kadar geniş bir yelpazede anlattım. Tüm bunları bir seferde ezberlemek zorunda değilsin. Önemli olan, bir sorunla karşılaştığında “bunu regex ile çözebilirim” diye düşünmeye başlamak ve denemeye devam etmektir.
Bir sonraki yazıda sed ile regex kullanımına bakacağız. grep‘in bulduğunu sed ile değiştirip, dönüştürüp, silebileceğini göreceğiz. O birleşim gerçekten güçlü.