Ders 15 / 24
Satır Filtreleme
Örüntüye göre satır seçme, sayma ve tersini alma, sözcük ve tam satır eşleşmesi, sabit dizgi kipi, çok dosyalı arama ve çıkış kodunun koşul olarak kullanımı.
İçindekiler
Kalıp dili kuruldu. Onu uygulayan ilk araç, bir akıştan kalıba uyan satırları seçen süzgeçtir. Bu araç kabuk metin işlemenin en çok çağrılanıdır ve seçeneklerinin çoğu, “eşleşen satırları yaz” davranışını başka bir soruya dönüştürür.
Bu ders o soruları ve her birinin doğru seçeneğini ele alır.
Seçmek, Saymak, Konumlandırmak
Öntanımlı davranış, eşleşen satırları yazmaktır. -n seçeneği satır numarasını ekler:
grep -n '500' erisim.log
8:192.168.1.5 - - [07/Feb/2024:09:17:22 +0000] "GET /api/veri HTTP/1.1" 500 180 13:192.168.1.5 - - [07/Feb/2024:09:21:38 +0000] "GET /api/veri HTTP/1.1" 500 180 27:10.0.2.7 - - [07/Feb/2024:09:35:44 +0000] "POST /api/veri HTTP/1.1" 500 180
-c yalnızca sayıyı verir. Sayılan şey eşleşen satır sayısıdır, eşleşme sayısı
değildir:
grep -Ec '\.' erisim.log grep -Eo '\.' erisim.log | wc -l
30
131
Otuz satırın hepsinde en az bir nokta var; toplam nokta sayısı 131. Ayrım, “kaç istek 404
aldı” ile “404 dizgisi kaç kez geçti” sorularını ayırır. Eşleşme sayısı isteniyorsa -o
ile her eşleşme ayrı satıra dökülür ve sayılır.
grep -c '' yazımı, boş kalıp her satırla eşleştiği için satır sayımı verir ve wc -l
gibi hizalama boşluğu üretmez:
grep -c '' erisim.log
30
Tersini Almak
-v seçeneği eşleşmeyen satırları seçer. Süzme işlerinde en çok kullanılan seçenektir;
gürültü satırlarını atmanın doğrudan yoludur.
grep -vc '" 200 ' erisim.log
13
Otuz istekten on üçü 200 dışında bir kodla yanıtlanmış. -v ile -c birlikte
kullanılabilir; -v ile -o birlikte anlamsızdır, çünkü eşleşmeyen satırda yazılacak
eşleşme yoktur.
Eşleşmenin Sınırlarını Daraltmak
Üç seçenek, kalıbın satırın hangi bölümüyle eşleşeceğini kısıtlar.
-i büyük–küçük harf ayrımını kaldırır. -w kalıbın sözcük sınırlarında başlayıp
bitmesini ister. -x kalıbın satırın tamamıyla eşleşmesini ister.
printf '%s\n' 'GET /a' 'get /b' 'GETTER /c' > kucukbuyuk.txt grep -c 'GET' kucukbuyuk.txt grep -ic 'GET' kucukbuyuk.txt grep -wc 'GET' kucukbuyuk.txt
2 3 1
Dosya GET /a, get /b ve GETTER /c satırlarını içeriyor. Öntanımlı arama ikisini,
harf duyarsız arama üçünü, sözcük araması yalnızca birini seçti — GETTER içindeki GET
sözcük değildir.
-x, çapa yazmanın kısayoludur:
printf '%s\n' '404' '4040' > kod.txt grep -c '404' kod.txt grep -xc '404' kod.txt
2 1
Dosyadaki 4040 satırı, çapasız kalıba uydu. Tam eşleşme isteyen sınamalarda -x
unutulursa sonuç sessizce fazla çıkar.
Sabit Dizgi Kipi
-F seçeneği kalıbı düzenli ifade olarak değil, harfi harfine dizgi olarak yorumlar.
printf '%s\n' 'a.b' 'axb' > nokta.txt grep -c 'a.b' nokta.txt grep -Fc 'a.b' nokta.txt
2 1
-F iki nedenle önemlidir. Birincisi doğruluk: kalıp bir değişkenden — kullanıcı
argümanından, dosya adından, yapılandırma değerinden — geliyorsa içindeki ., *, [
karakterleri kalıp olarak yorumlanır ve arama beklenenden geniş sonuç verir. İkincisi,
kullanıcı girdisinin kalıp olarak kullanılması bir güvenlik sınırıdır: hazırlanmış bir
kalıp, eşleştirme maliyetini kasıtlı olarak patlatabilir.
Kural: kalıbın kendisini siz yazmadıysanız -F kullanın.
Kalıplar bir dosyada tutulabilir; -f seçeneği her satırı ayrı kalıp sayar:
printf '%s\n' '403' '500' > kaliplar.txt grep -Fcf kaliplar.txt erisim.log
5
Çok Dosyalı Arama
Birden çok dosya verildiğinde çıktının başına dosya adı eklenir:
mkdir -p kutuk-dizin head -10 erisim.log > kutuk-dizin/pazartesi.log tail -10 erisim.log > kutuk-dizin/sali.log grep -c '404' kutuk-dizin/*.log
kutuk-dizin/pazartesi.log:1 kutuk-dizin/sali.log:2
-h bu öneki bastırır, -H tek dosyada bile ekler. Betikte çıktı ayrıştırılacaksa
seçeneği açıkça yazmak gerekir; öneki dosya sayısına göre değişen bir çıktı, kırılgan bir
dayanaktır.
-l eşleşme bulunan dosyaların adını, -L bulunmayanların adını verir:
grep -l '500' kutuk-dizin/*.log
kutuk-dizin/pazartesi.log kutuk-dizin/sali.log
-r bir dizin ağacında özyinelemeli arar. Dosyaların ziyaret sırası dosya sisteminin
verdiği sıradır ve gerçekleştirimden gerçekleştirime değişir; sıralı çıktı gerekiyorsa
sonuç ayrıca sort ile sıralanmalıdır.
-m N her dosyada ilk N eşleşmeden sonra durur. Büyük dosyalarda “var mı” sorusunun
yanıtı için tüm dosyayı okumayı önler.
Bağlam Satırları
-A N eşleşmeden sonraki, -B N önceki, -C N her iki yandaki N satırı da yazar.
Bloklar arasına -- ayıracı konur.
grep -A 1 '" 500 ' erisim.log | head -4
192.168.1.5 - - [07/Feb/2024:09:17:22 +0000] "GET /api/veri HTTP/1.1" 500 180 10.0.0.12 - - [07/Feb/2024:09:18:00 +0000] "GET /api/veri HTTP/1.1" 200 3300 -- 192.168.1.5 - - [07/Feb/2024:09:21:38 +0000] "GET /api/veri HTTP/1.1" 500 180
Hata ayıklamada bir hatanın öncesindeki ve sonrasındaki isteklere bakmak için kullanılır. Ayıraç satırı çıktının biçimini bozduğu için, çıktısı başka bir araca akacak hatlarda bağlam seçenekleri kullanılmaz.
Çıkış Kodunu Koşul Olarak Kullanmak
-q seçeneği hiçbir şey yazmaz; ilk eşleşmede durur ve sonucu yalnızca çıkış koduyla
bildirir. Betikte “var mı” sorusunun doğru biçimi budur:
if grep -q '" 500 ' erisim.log; then echo "sunucu hatasi var" fi
sunucu hatasi var
grep -c ... > /dev/null yazımı aynı işi görmez: -c eşleşme olmasa da 0 yazar ve
çıkış kodu yine eşleşme durumuna bağlıdır, ama tüm dosya okunur. -q ilk eşleşmede
durur.
Çıkış Kodları dersinde kurulan üç kodlu sözleşme burada işler: 0 bulundu, 1
bulunamadı, 2 dosya hatası. Katı kip altında çalışan betiklerde “bulunamadı” durumunun
betiği durdurmaması için koşul olarak kullanılmalı ya da || true eklenmelidir.
Betiğe Uygulama
rapor.sh iki yeni bölüm kazanır. Birincisi, kütükteki bozuk satırları sayar; ikincisi
hata döndüren yolları listeler.
kutuk=erisim.log SATIR_KALIBI='^[0-9.]+ - - \[[^]]+\] "[A-Z]+ [^ ]+ HTTP/[0-9.]+" [0-9]{3} [0-9]+$' bozuk=$(grep -Evc "$SATIR_KALIBI" "$kutuk") if [ "$bozuk" -gt 0 ]; then uyari "$bozuk satir beklenen bicimde degil ve sayimlara dahil" fi bolum "Hata donduren yollar" grep -E '" [45][0-9]{2} ' "$kutuk" | cut -d' ' -f7 | sort | uniq -c | sort -rn
Bozuk satırlı bir kütükle çalıştırıldığında:
./rapor.sh tumu.log
Uyarı standart hataya düşer, rapor standart çıktıya devam eder. Temiz kütükte hata döndüren yollar bölümü şunu verir:
4 /yok.html 3 /api/veri 2 /gizli
grep -E '" [45][0-9]{2} ' kalıbındaki tırnak ve boşluklar, durum kodu alanını
kütükteki başka bir sayıdan ayırır. Bu, alan kavramının kalıpla taklit edilmesidir;
sonraki derslerde alan tabanlı araçlar aynı işi konumla yapacak ve kalıba gerek
kalmayacak.
Filtrelemenin Hattaki Yeri
Boru hattı dersinde eşzamanlılık kurulmuştu. Bunun pratik sonucu bir sıralama kuralıdır: veriyi küçülten adımı hattın başına koyun.
grep -E '" [45][0-9]{2} ' "$kutuk" | cut -d' ' -f7 | sort | uniq -c
Bu hatta grep otuz satırı dokuza indirir; sort dokuz satır sıralar. Sıralama sonda
olsaydı otuz satır sıralanırdı. Sıralama maliyetinin girdi büyüklüğüne bağlı olması —
Algoritmalar kursunda gösterildiği gibi — bu kuralın gerekçesidir.
Kural bir istisna taşır: filtreleme, sonraki adımın ihtiyaç duyduğu satırları atmamalıdır. Bağlam gerektiren dönüşümlerde süzme sonraya bırakılır.
Özet
-ceşleşen satırları sayar, eşleşmeleri değil; eşleşme sayısı-oile satırlara dökülüp sayılır.-vseçimi tersine çevirir;-wsözcük,-xtam satır eşleşmesi ister.-Fkalıbı harfi harfine yorumlar ve dışarıdan gelen kalıplarda zorunludur.- Çok dosyalı aramada çıktı öneki dosya sayısına göre değişir; betikte
-hya da-Haçıkça yazılır. -qhiçbir şey yazmaz ve ilk eşleşmede durur; betikte varlık sınamasının doğru biçimidir.- Veriyi küçülten filtre, boru hattının başına konur.
Sonraki Adım
Filtreleme satırları seçer ama değiştirmez. Kütükteki zaman damgasını yeniden biçimlendirmek, alan sınırlayıcılarını sadeleştirmek ya da bir alanı gizlemek için satırın kendisini dönüştürmek gerekir. Sonraki ders akış editörünü ele alır: yerine koyma, adres ve aralık seçimi, geri başvurularla yeniden yazma ve yerinde düzenleme seçeneğinin gerçekleştirimler arasındaki uyumsuzluğu.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.