Şöyle bir dosyam var, adı dosya.txt:
12.09.2014 Cihan 1993
01.10.2017 Zeynep 1992
02.05.2013 Mutlu 1991
Başlık satırı yok, virgülle ayrılmış değil, sabit uzunluklu.
Yeni öğrendiğim bir yöntem ile bu dosyayı okumak istedim:
gc dosya.txt | % {
$a,$b,$c=$_ -split '(.{10}) (.{6}) (.{4})'
[PSCustomObject]@{
Tarih=$a
Isim=$b
Yil=$c
}
}Ama bu, beklediğim sonucu üretmedi. Burada
(.{10}) : 10 karakter uzunluğunda sabit genişlikli bir alan olarak tarih verisini,
(.{6}) : 6 karakter uzunluğunda sabit genişlikli bir alan olarak isim verisini,
(.{4}) : 4 karakter uzunluğunda sabit genişlikli bir alan olarak yil verisini
bulacak capture group'lar. Yukarıdaki ayrıştırıcı ile elde ettiğim sonuç aşağıdaki gibiydi:
Tarih Isim Yil
----- ---- ---
12.09.2014 {Cihan , 1993, }
01.10.2017 {Zeynep, 1992, }
02.05.2013 {Mutlu , 1991, }
Evet, tarih alanı boş ve tüm sütunlar kaymış. Hatta yıl sütunundan sonra virgülle ayrılmış bir boş alan daha var. Ben bunu şu şekilde çözmüştüm:
Get-Content veriler.txt | % {
$a0,$a,$b,$c,$1=($_ -split '(.{10}) (.{6}) (.{4})')
[PSCustomObject]@{
Tarih=$a
Isim=$b
Yil=$c
}
}Yani burada $a0 ve $a1 değişkenlerini hiç hesaba dahil etmedim. Sonuç istediğim gibi oldu:
Tarih Isim Yil
----- ---- ---
12.09.2014 Cihan 1993
01.10.2017 Zeynep 1992
02.05.2013 Mutlu 1991
Ama kod içime sinmedi. Neden gereksiz değişkenler kullanmak zorunda kaldım? Her bilişimcinin yapacağı gibi konuyu ayrıntılı olarak arama motorlarında aratmak yerine, Claude'a sordum. Cevabı şöyle:
Normal -split davranışı: Deseni bir "ayırıcı" (delimiter) olarak kullanır, ayırıcıyı bulur, ayırıcıyı atar ve geriye kalan parçaları döndürür.
Capture group'lu -split davranışı: Deseni yine ayırıcı olarak kullanır, ama bu sefer ayırıcıyı atmaz — parantez içindeki her bir capture group'un eşleştiği metni de sonuç dizisine ekler. Yani split hem "ayırıcının dışında kalan kısımları" hem de "ayırıcının içindeki (parantezlenmiş) kısımları" döndürür.
Bana çözüm önerileri olarak da şunları verdi:
1. Boş elemanları where-object ile süzmek
gc dosya.txt | % {
$a,$b,$c=($_ -split '(.{10}) (.{6}) (.{4})') | Where-Object { $_ -ne "" }
[PSCustomObject]@{
Tarih=$a
Isim=$b
Yil=$c
}
}2. -split yerine -match kullanmak
gc dosya.txt | % {
if ($_ -match '^(.{10}) (.{6}) (.{4})$') {
[PSCustomObject]@{
Tarih=$Matches[1]
Isim=$Matches[2].Trim()
Yil=$Matches[3]
}
}
Hiç yorum yok:
Yorum Gönder