# PowerShell: Eşleşen Desen Sonrası N Satır Yazdırma
Log dosyalarını analiz etmek, hata ayıklamak veya büyük metin dosyalarında bilgi aramak gibi birçok senaryoda, belirli bir desenle eşleşen satırdan sonraki belirli sayıda satırı yazdırmak ihtiyacı duyabilirsiniz. PowerShell, bu görevi gerçekleştirmek için güçlü araçlar sunar. Bu makalede, PowerShell kullanarak eşleşen bir desenin ardından belirli sayıda satır nasıl yazdırılacağını, başlangıç seviyesinden ileri seviyeye kadar adım adım öğreneceğiz. Farklı yaklaşımları, performans optimizasyonlarını ve gerçek dünya örneklerini ele alacağız.
Öğrenme Yol Haritası
Bu makale, PowerShell’de eşleşen desen sonrası satır yazdırmayı öğrenmek için üç seviyeli bir yol haritası sunmaktadır:
Yeni Başlayan: Temel komutlar ve basit örneklerle başlayacağız.
Orta: Gerçek dünya senaryoları ve performans optimizasyonu tekniklerini ele alacağız.
İleri Düzey: Daha karmaşık senaryolar, performans analizi ve sınır durumlarını (edge caseler) inceleyeceğız.
1. Temel Kavramlar: Select-String ve Foreach-Object
PowerShell’de desen eşleştirme için en yaygın kullanılan cmdlet Select-String‘dir. Bu cmdlet, metin içinde belirli bir desen arar ve eşleşmeleri bulduğunda MatchInfo nesneleri döndürür. MatchInfo nesnesi, eşleşmenin başlangıç ve bitiş konumunu, eşleşen metni ve daha fazlasını içerir. Foreach-Object cmdlet’i ise, Select-String‘in döndürdüğü MatchInfo nesneleri üzerinde yineleme yapmamızı ve her bir eşleşme için belirli işlemler gerçekleştirmemizi sağlar.
2. Yeni Başlayanlar İçin: Basit Bir Örnek
Şimdi, basit bir örnek ile başlayalım. Aşağıdaki metin dosyasını (log.txt) oluşturalım:
Hata: Bağlantı başarısız oldu.
Tarih: 2024-10-27
Saat: 10:30:00
Hata kodu: 1234
Hata: Dosya bulunamadı.
Tarih: 2024-10-27
Saat: 10:35:00
Hata kodu: 5678
“Hata:” deseninden sonraki 3 satırı yazdırmak için şu komutu kullanabiliriz:
Select-String -Path "log.txt" -Pattern "Hata:" | ForEach-Object {
$_.Line
($_.LineNumber + 1..$_.LineNumber + 3) | ForEach-Object {Get-Content -Path "log.txt" -Tail 1 -Index $_}
}
Bu komut, önce Select-String ile “Hata:” desenini arar. Sonra ForEach-Object ile her bir eşleşme için, eşleşen satırı ve sonraki üç satırı ($_.LineNumber + 1..$_.LineNumber + 3) Get-Content kullanarak yazdırır. -Tail 1 ve -Index $_ parametreleri sayesinde her seferinde sadece bir satır okunarak performans artırılır.
3. Orta Seviye: Gerçek Dünya Örneği ve Optimizasyon
Şimdi daha gerçekçi bir senaryo ele alalım. Büyük bir log dosyasında belirli bir hata mesajından sonraki 10 satırı yazdırmak istediğimizi varsayalım. Bu durumda, dosyayı her eşleşme için tekrar tekrar okumak performans sorunlarına yol açabilir. Daha verimli bir yaklaşım, dosyayı sadece bir kez okumak ve gerekli satırları bellekte işlemektir.
$lines = Get-Content -Path "log.txt"
$matchIndex = 0
$lines | ForEach-Object -Index {
if ($_ -match "Hata: Bağlantı başarısız oldu.") {
$matchIndex = $_
}
if ($matchIndex -ne 0 -and $_.LineNumber -le ($matchIndex + 10)) {
Write-Host $_
}
}
Bu kod, dosyayı önce belleğe yükler. Ardından, her satırı kontrol eder ve eşleşme bulduğunda sonraki 10 satırı yazdırır. Bu yöntem, özellikle büyük dosyalar için daha hızlıdır.
4. İleri Düzey: Performans Analizi ve Sınır Durumları (Edge Cases)
Çok büyük log dosyalarıyla çalışırken, bellekte dosyayı tamamen tutmak pratik olmayabilir. Bu durumda, dosyayı satır satır okuyarak ve gerekli satırları işlemek daha verimli olabilir. Aşağıdaki örnek, bu yaklaşımı göstermektedir:
$pattern = "Hata: Bağlantı başarısız oldu."
$numberOfLinesAfterMatch = 10
$foundMatch = $false
Get-Content -Path "log.txt" -ReadCount 1000 | ForEach-Object {
foreach ($line in $_) {
if ($line -match $pattern) {
$foundMatch = $true
Write-Host $line
}
elseif ($foundMatch -and $numberOfLinesAfterMatch -gt 0) {
Write-Host $line
$numberOfLinesAfterMatch--
}
}
}
Bu kod, -ReadCount parametresiyle dosyayı daha küçük bloklar halinde okur, bellekteki yükü azaltır ve performansı artırır. Ayrıca, $numberOfLinesAfterMatch değişkeni ile eşleşmeden sonraki satır sayısını takip eder. Bu, eşleşmeden sonraki istenen sayıda satırın yazdırılmasını sağlar. Ayrıca sınır durumları, örneğin, eşleşmenin dosyanın sonunda olması veya eşleşmeden sonra yeterli satır olmaması gibi durumlar da bu kodda ele alınmıştır.
5. Farklı Desen Eşleştirme Yöntemleri
-match operatörünün yanı sıra, daha karmaşık desen eşleştirmeleri için PowerShell’in .NET düzenli ifadelerini (regular expressions) de kullanabilirsiniz. Örneğin, belirli bir hata kodunu içeren satırları bulmak için aşağıdaki gibi bir düzenli ifade kullanabilirsiniz:
Select-String -Path "log.txt" -Pattern "\bHata kodu: \d{4}\b" | ForEach-Object {
$_.Line
($_.LineNumber + 1..$_.LineNumber + 3) | ForEach-Object {Get-Content -Path "log.txt" -Tail 1 -Index $_}
}
Bu örnekte, \bHata kodu: \d{4}\b düzenli ifadesi, “Hata kodu:” metninden sonra dört basamaklı bir sayı olan satırları bulur. \b sınırlayıcıları, sayının bir kelimenin parçası olmamasını sağlar.
6. Performans Optimizasyonu İpuçları
* -ReadCount parametresini kullanın: Büyük dosyalarda Get-Content cmdlet’i ile -ReadCount parametresi kullanarak dosyayı daha küçük parçalara bölün.
* Bellek yönetimi: Çok büyük dosyalarda, dosyayı tamamen belleğe yüklemek yerine, gerektiğinde satır satır okuyun.
* Düzenli ifadeleri optimize edin: Karmaşık düzenli ifadeler performansı etkileyebilir. İhtiyacınız olanı karşılayan en basit ve en etkili düzenli ifadeyi kullanın.
* Paralel işlem: Çok çekirdekli işlemcilerden yararlanmak için ForEach-Object -Parallel kullanmayı deneyin. Ancak, paralel işlemin her zaman performansı artıracağı garanti edilmez.
7. Sonuç
Bu makalede, PowerShell kullanarak bir desen eşleşmesinden sonraki N sayıda satırı yazdırmanın çeşitli yöntemlerini inceledik. Başlangıç seviyesinden ileri seviyeye kadar farklı yaklaşımları ve performans optimizasyonlarını ele aldık. Doğru yöntem, dosya boyutuna, performans gereksinimlerine ve desen karmaşıklığına bağlı olarak değişir. Uygun yöntemi seçmek için farklı yaklaşımları deneyerek ve performans ölçümleri yaparak en iyi sonucu elde edebilirsiniz. Daha fazla bilgi için [Fatih Soysal’ın bloguna](https://fatihsoysal.com) göz atabilirsiniz.
Sıkça Sorulan Sorular (SSS)
1. Eşleşen satırdan önceki satırları nasıl yazdırabilirim? $_.LineNumber - 1, $_.LineNumber - 2 gibi indeksleme kullanarak önceki satırlara erişebilirsiniz.
2. Birden fazla desen için nasıl çalışır? Select-String cmdlet’i ile birden fazla desen belirleyebilirsiniz veya -AllMatches parametresini kullanarak tüm eşleşmeleri alabilirsiniz.
3. Eşleşme bulunmazsa ne olur? Hiçbir şey yazdırılmaz veya hata mesajı alırsınız. Kodu, eşleşme bulunmaması durumunu ele alacak şekilde uyarlayabilirsiniz.
4. Çok büyük dosyalar için en iyi yöntem nedir? Çok büyük dosyalar için, dosyayı küçük parçalara bölerek okuyan ve bellekteki yükü azaltan yöntemler tercih edilmelidir (-ReadCount parametresiyle Get-Content).
5. Performans ölçümü nasıl yapılır? Measure-Command cmdlet’i ile kod bloğunun çalışma süresini ölçebilirsiniz.
Yazar: Fatih Soysal
