İçeriğe geç
academia.sh

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

  • -c eşleşen satırları sayar, eşleşmeleri değil; eşleşme sayısı -o ile satırlara dökülüp sayılır.
  • -v seçimi tersine çevirir; -w sözcük, -x tam satır eşleşmesi ister.
  • -F kalı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 -h ya da -H açıkça yazılır.
  • -q hiç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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat