grep Komutu: Metin Arama ve Regex ile Güçlü Kullanım

Terminal’de geçirdiğim yıllara bakınca, grep komutunu bilmeden Linux’ta gerçekten verimli çalışmanın mümkün olmadığını söyleyebilirim. Log dosyaları karıştırırken, config dosyalarında bir şey ararken, büyük kod tabanlarında belirli bir fonksiyon adını bulmaya çalışırken… grep her seferinde imdadıma yetişti. Bu yazıda grep‘i yüzeysel düzeyde değil, gerçekten ustaca kullanabilmek için bilmeniz gereken her şeyi ele alacağım.

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

grep, Global Regular Expression Print kelimelerinin kısaltmasıdır. Temel görevi, girilen bir deseni (pattern) metin içinde satır satır aramak ve eşleşen satırları ekrana basmaktır. 1973 yılında Ken Thompson tarafından ed metin editöründeki bir özellikten türetilmiş olup, Unix tarihinin en köklü araçlarından biridir.

Çalışma mantığı oldukça basittir: Bir veya birden fazla dosyayı okur, her satırı verilen desenle karşılaştırır ve eşleşen satırları standart çıktıya yazar. Ama bu basit mantığın üzerine inşa edilmiş onlarca seçenek ve regex gücü, grep‘i son derece güçlü bir araca dönüştürür.

Temel sözdizimi şu şekildedir:

grep [seçenekler] 'desen' dosya(lar)

Temel Kullanım Örnekleri

Başlangıç olarak en sık kullanılan senaryolara bakalım. Bir config dosyasında belirli bir kelimeyi aramak istiyorsunuz:

grep 'PasswordAuthentication' /etc/ssh/sshd_config

Bu komut, sshd_config dosyasındaki PasswordAuthentication kelimesini içeren satırı bulup gösterir. Büyük küçük harf duyarlılığını kapatmak için -i seçeneğini kullanabilirsiniz:

grep -i 'passwordauthentication' /etc/ssh/sshd_config

Birden fazla dosyada arama yapmak için dosya adlarını yan yana yazabilirsiniz:

grep 'error' /var/log/syslog /var/log/auth.log

Önemli Seçenekler ve Anlamları

grep‘in gücü büyük ölçüde seçeneklerinden gelir. En çok işinize yarayacak olanları şöyle sıralayabilirim:

  • -i: Büyük küçük harf duyarlılığını devre dışı bırakır
  • -v: Eşleşmeyen satırları gösterir (ters arama)
  • -r: Alt dizinlerle birlikte özyinelemeli arama yapar
  • -R: -r gibi çalışır ama sembolik linkleri de takip eder
  • -l: Sadece eşleşme bulunan dosyaların adını gösterir
  • -L: Eşleşme bulunmayan dosyaların adını gösterir
  • -n: Eşleşen satırların satır numaralarını gösterir
  • -c: Her dosya için kaç satırın eşleştiğini sayar
  • -o: Sadece eşleşen kısmı gösterir, tüm satırı değil
  • -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 hem öncesinde hem sonrasında n satır gösterir (Context)
  • -w: Sadece tam kelime eşleşmelerini bulur
  • -x: Sadece tam satır eşleşmelerini bulur
  • -e: Birden fazla desen belirtmek için kullanılır
  • -f: Desenleri bir dosyadan okur
  • -q: Sessiz mod, çıktı üretmez sadece exit kodu döner
  • -m [n]: En fazla n eşleşme bulduktan sonra durur
  • –color: Eşleşen kısımları renklendirir

Özyinelemeli Arama: Dizinlerde Gezinmek

Sistem yöneticiliğinde en çok kullandığım özelliklerden biri özyinelemeli aramadır. Bir web sunucusunun config dizininde belirli bir directive’i aramak istediğinizde:

grep -r 'ServerName' /etc/apache2/

Hangi dosyada bulunduğunu görmek ve satır numarasını da almak için:

grep -rn 'max_connections' /etc/mysql/

Sadece belirli uzantılardaki dosyalarda arama yapmak için --include parametresini kullanabilirsiniz:

grep -r --include="*.conf" 'timeout' /etc/

Tersine, belirli dosyaları aramadan dışlamak için --exclude kullanılır:

grep -r --exclude="*.log" 'kritik_hata' /var/www/html/

Regex ile Gerçek Güç

İşte grep‘in asıl büyüsü burada başlıyor. Düzenli ifadeler (regular expressions, regex) ile son derece esnek aramalar yapabilirsiniz.

Temel Regex Karakterleri

  • .: Herhangi bir tek karakterle eşleşir
  • *: Kendinden önceki karakterin sıfır veya daha fazla tekrarıyla eşleşir
  • +: Kendinden önceki karakterin bir veya daha fazla tekrarıyla eşleşir (ERE)
  • ?: Kendinden önceki karakterin sıfır veya bir kez geçmesiyle eşleşir (ERE)
  • ^: Satır başını temsil eder
  • $: Satır sonunu temsil eder
  • []: Karakter sınıfı tanımlar
  • [^]: Belirtilen karakterlerin dışındakilerle eşleşir
  • b: Kelime sınırını temsil eder
  • {n,m}: Belirtilen aralıkta tekrar sayısını ifade eder (ERE)

Temel Regex Örnekleri

Satır başında belirli bir kelime araması:

grep '^root' /etc/passwd

Satır sonu araması, boş satırları bulmak için:

grep -c '^$' dosya.txt

Belirli karakterlerden oluşan desenleri aramak:

grep '[0-9]{3}-[0-9]{3}-[0-9]{4}' iletisim.txt

Bu komut, 555-123-4567 formatındaki telefon numaralarını bulur.

Genişletilmiş Regex: grep -E veya egrep

grep -E komutu (ya da egrep), genişletilmiş düzenli ifadeleri destekler. Bu mod, özellikle +, ?, | ve () gibi karakterleri backslash olmadan kullanmanıza olanak tanır.

grep -E 'error|warning|critical' /var/log/syslog

Bu komut, syslog dosyasında error, warning veya critical kelimelerinden herhangi birini içeren satırları bulur. Log analizi yaparken bu komutun kaç kez hayatımı kurtardığını anlatamam.

IP adresi araması için güzel bir örnek:

grep -E 'b([0-9]{1,3}.){3}[0-9]{1,3}b' access.log

E-posta adresi gibi görünen şeyleri bulmak için:

grep -E '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,}' kullanici_listesi.txt

Gerçek Dünya Senaryoları

Senaryo 1: Apache/Nginx Access Log Analizi

Bir web sunucusunu yönetirken log dosyaları hayati önem taşır. Belirli bir IP adresinin son dakikalarda kaç istek gönderdiğini görmek istediğinizde:

grep '192.168.1.105' /var/log/nginx/access.log | grep -c "GET|POST"

404 hataları veren istekleri bulmak ve hangi URL’lere yapıldığını görmek:

grep ' 404 ' /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

Burada grep‘i awk, sort ve uniq ile birleştirerek çok güçlü bir analiz aracı elde ediyoruz.

Senaryo 2: SSH Brute Force Tespiti

Auth log dosyasını izleyerek başarısız giriş denemelerini tespit etmek:

grep -i 'failed password' /var/log/auth.log | grep -oE 'b([0-9]{1,3}.){3}[0-9]{1,3}b' | sort | uniq -c | sort -rn | head -10

Bu komut zinciri şu işlemleri yapar: önce başarısız parola girişlerini filtreler, sonra bu satırlardan IP adreslerini çıkarır, ardından tekrar sayısına göre sıralar. Böylece hangi IP’nin en çok deneme yaptığını görebilirsiniz.

Başarıyla giriş yapan kullanıcıları bulmak:

grep 'Accepted password|Accepted publickey' /var/log/auth.log | grep -v 'your_admin_user'

Senaryo 3: Uygulama Log Takibi

Bir Java uygulamasının log dosyasında stack trace’leri bulmak ve öncesindeki context satırlarını da görmek:

grep -n 'Exception|Error' /var/log/myapp/application.log | tail -50

Daha da iyisi, Exception geçen satırdan sonraki 10 satırı da görmek için:

grep -A 10 'NullPointerException' /var/log/myapp/application.log

Senaryo 4: Konfigürasyon Yönetimi

Bir sunucu parkında belirli bir config parametresinin set edilip edilmediğini kontrol etmek:

grep -r 'net.ipv4.ip_forward' /etc/sysctl.conf /etc/sysctl.d/

Crontab’larda belirli bir komut ya da script’in çalışıp çalışmadığını görmek:

grep -r 'backup.sh' /var/spool/cron/ /etc/cron.d/ /etc/crontab

grep ile Pipeline Kullanımı

grep‘in asıl gücü, diğer komutlarla pipeline içinde kullanıldığında ortaya çıkar.

Çalışan processler arasında arama:

ps aux | grep -v grep | grep 'nginx'

Burada -v grep kısmına dikkat edin. ps aux | grep 'nginx' komutunu çalıştırdığınızda, grep’in kendisi de process listesinde görünür. Bu yüzden grep -v grep ile grep processini sonuçlardan çıkarıyoruz.

Disk kullanımında belirli bir eşiği aşan mount point’leri bulmak:

df -h | grep -E '^/dev' | grep -v 'tmpfs' | awk '{print $5, $6}' | sort -rn

Açık portları listelemek ve belirli bir servisi bulmak:

ss -tulpn | grep ':80|:443|:8080'

Perl Compatible Regular Expressions: grep -P

grep -P seçeneği ile Perl uyumlu düzenli ifadeler kullanabilirsiniz. Bu mod, d (rakam), w (kelime karakteri), s (boşluk), lookahead ve lookbehind gibi ileri düzey regex özelliklerini destekler.

grep -P 'd{4}-d{2}-d{2}' logfile.txt

Bu komut 2024-01-15 formatındaki tarihleri bulur.

Lookahead kullanımı, örneğin “ERROR” kelimesinden önce gelen timestamp’i bulmak:

grep -oP '^d{4}-d{2}-d{2} d{2}:d{2}:d{2}(?=.*ERROR)' app.log

Şifre içermeyen satırları bulmak (negatif lookahead):

grep -P '^(?!.*password).*user' config.txt

Birden Fazla Desen Kullanımı

Birden fazla arama desenini aynı anda kullanmak için -e seçeneği kullanılır:

grep -e 'error' -e 'warning' -e 'fatal' /var/log/syslog

Ya da desenleri bir dosyaya yazıp o dosyayı kullanabilirsiniz:

cat arama_desenleri.txt
error
warning
critical
fatal

grep -f arama_desenleri.txt /var/log/syslog

Bu yaklaşım, özellikle monitoring script’leri yazarken çok işe yarar. Desen dosyasını güncelleyerek script’i değiştirmeden izlediğiniz şeyleri değiştirebilirsiniz.

Dosya Listesi Çıktısı ve Script Kullanımı

Script yazarken grep‘in exit code’unu kullanabilirsiniz. Eşleşme bulunduğunda 0, bulunmadığında 1 döner:

if grep -q 'PasswordAuthentication yes' /etc/ssh/sshd_config; then
    echo "UYARI: SSH parola girisi aktif! Kapatilmasi oneriliyor."
    sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
    systemctl restart sshd
fi

-q (quiet/silent) seçeneği hiçbir çıktı üretmez, sadece exit code döner. Bu, script’lerde koşul kontrolü yaparken idealdir.

Hangi dosyaların belirli bir içeriğe sahip olduğunu bulmak:

grep -rl 'TODO|FIXME|HACK' /var/www/html/ --include="*.php"

Bu komut, PHP dosyalarında TODO, FIXME veya HACK yorum etiketleri içerenlerin listesini verir. Code review öncesi bu komutu çalıştırmayı alışkanlık haline getirdim.

Renkli Çıktı ve Görselleştirme

Modern terminal ortamlarında grep --color=auto ile eşleşen kısımlar renklendirilir. Bunu kalıcı hale getirmek için .bashrc dosyanıza ekleyebilirsiniz:

alias grep='grep --color=auto'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'

fgrep: Sabit String Araması

grep -F veya fgrep, regex karakterlerini yorumlamadan düz metin araması yapar. Arama terimi regex özel karakterleri içeriyorsa ve bunları literal olarak aramak istiyorsanız idealdir:

fgrep '192.168.1.1/24' /etc/network/interfaces

Eğer normal grep kullansaydınız, . karakteri regex’te “herhangi bir karakter” anlamına gelirdi ve yanlış eşleşmeler çıkabilirdi. fgrep bu sorunu ortadan kaldırır.

Büyük Dosyalarda Performans

Çok büyük log dosyalarında grep kullanırken performans önemli hale gelir. Bazı ipuçları:

--mmap seçeneği bazı sistemlerde bellek eşlemeli I/O kullanarak hız artışı sağlar. Ama asıl kazanım, binary dosyaları atlamak için --include ve --exclude seçeneklerini doğru kullanmaktan gelir.

Sıkıştırılmış log dosyalarında zgrep kullanabilirsiniz, grep‘i .gz dosyalarına uygulamadan önce dosyayı açmaya gerek yoktur:

zgrep 'ERROR' /var/log/syslog.2.gz

Paralel arama için xargs ile birleştirme:

find /var/log -name "*.log" -newer /tmp/last_check | xargs grep -l 'CRITICAL'

Pratik İpuçları ve Sık Yapılan Hatalar

Boşluk içeren desenlerde tırnak kullanmayı unutmayın:

grep 'failed login attempt' /var/log/auth.log

Tırnak kullanmazsanız shell, boşluktan itibaren kelimeleri ayrı argüman olarak yorumlar.

Özel karakterleri escape etmeyi unutmayın:

grep '$HOME' script.sh

Burada $HOME‘u değişken olarak değil, literal string olarak aramak istiyoruz.

-w ile tam kelime araması yapın:

grep -w 'log' *.txt

Bu komut “log” kelimesini bulur ama “login”, “logout”, “catalog” gibi kelimeleri bulmaz.

Sonuç

grep, Linux sistem yöneticisinin araç çantasındaki en vazgeçilmez komutlardan biridir. Basit string aramalarından karmaşık regex desenlerine, log analizinden configuration yönetimine kadar geniş bir yelpazede kullanılabilir. Bu yazıda ele aldığımız temel seçenekler, regex temelleri, grep -E ve grep -P modları ile pipeline kullanımını özümsediğinizde, terminalde geçirdiğiniz süre çok daha verimli hale gelecektir.

Pratik yapmanın en iyi yolu, gerçek log dosyaları ve config dosyaları üzerinde denemeler yapmaktır. /var/log/ dizini bu konuda mükemmel bir pratik alanı sunar. grep‘i ne kadar çok kullanırsanız, regex desenleri o kadar doğal gelmeye başlar ve zamanla “hangi komutu kullanacağım” diye düşünmek yerine direkt komutu yazmaya başlarsınız. O noktaya geldiğinizde, gerçek anlamda bir Linux kullanıcısı olduğunuzu anlarsınız.

Bir yanıt yazın

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