Powershell'deki sort (aslında Sort-Object'in alias'ı) ile ilgilendikten komut satırındaki sort baştan biraz daha yavan gelmişti. Ama yine de çok güçlü. Temel amacı bir metin dosyasındaki verileri sıralamak. Örnek sabit uzunluklu alanlara sahip metin
veriler.txt dosyamızda aşağıdaki gibi bir veri olsun:
2014-09-12 Cihan 1993
2017-10-01 Zeynep 1992
2013-05-02 Mutlu 1991
3 sütun veri var. İlk sütun bir tarih alanı. Ama tarihler metin sıralaması yapılabilmesi için yıl-ay-gün şeklinde yazılmış. Aksi takdirde gün-ay-yıl şeklinde olan bir alanda metin sıralaması yapabilmek için tarih veri tipinden anlayan, hatta varklı formatlardaki tarihleri algılayabilen bir algoritma gerekli, ama bu sort ile imkansız. İkinci sütunumuz düz metin tabanlı isimlerden oluşuyor. Üçüncü sütun ise tamsayılardan oluşan yıl bilgisi.
Görüldüğü gibi bi veriler metin dosyasında sıralanmamış şekilde yer alıyor. Bu verileri örneğin tarihe göre sıralamak için
sort veriler.txt
demek yeterli. Tarih ilk sütunda yer aldığı için sonuç aşağıdaki gibi olacaktır
2013-05-02 Mutlu 1991
2014-09-12 Cihan 1993
2017-10-01 Zeynep 1992
İkinci sütundaki isimlere göre sıralamak için
sort veriler.txt /+12
komutu işimizi görür. İsimler sütununun ilk karakteri 12'den başladığı için /+12 anahtarı ile sıralamada dikkate alınacak bölümün 12. karakterden sonrası olduğunu belirttik. Burada önemli olan şu; sort aslında sadece isimlere göre sıralamıyor, isim+yıla göre sıralıyor. Önceki örnekte de bu geçerliydi. Sort tarih+isim+yıla göre sıraladı. /+12 anahtarı ile alınan (isim+yıla göre sıralama) sonuç şöyle:
2014-09-12 Cihan 1993
2013-05-02 Mutlu 1991
2017-10-01 Zeynep 1992
Üçüncü sütundaki yıl bilgisine göre sıralamak istersek, 199x'ların 1'i 19. karakterden başladığı için
sort veriler.txt /+19
Burada yıl sütununun sağında başka sütun olmadığı için doğal olarak sıralamaya sadece yıl bilgisi dahil edildi.
2013-05-02 Mutlu 1991
2017-10-01 Zeynep 1992
2014-09-12 Cihan 1993
Sıralama varsayılan olarak küçükten büyüğe (1'den 9'a, a'dan z'ye) yapılır. Sıralamayı ters çevirmek için /R anahtarı kullanılabilir.
sort veriler.txt /+19 /R
sonuç:
2014-09-12 Cihan 1993
2017-10-01 Zeynep 1992
2013-05-02 Mutlu 1991
İlk örnekten beri vurguladığım "sıralamaya dahil edilen alan uzunluğu"nu kısıtlamak için
/REC anahtarı kullanılabilir. Örneğin sıralamayı sadece ayın gününe göre yapmak için sıralmaya dahil edilecek veriyi 9'dan başlatıp 2 karakter uzunluğunda tutmalıyız:
sort veriler.txt /+9 /REC 2
Bu şekilde şu sonucu elde ederiz:
2017-10-01 Zeynep 1992
2013-05-02 Mutlu 1991
2014-09-12 Cihan 1993
Bir de bu sıralanmış çıktıyı başka bir dosyaya yazmak istersek /O anahtarını şu şekilde kullanabiliriz:
sort veriler /+9 /REC 2 /O sirali.txt
Eğer bu dosyayı Powershell'de sadece tarihe göre sıralamak (aslında tüm satıra göre) istersek şu olabilir:
PS C:\>Get-Content veriler.txt | Sort-Object
Ama bu verileri isim veya yıla göre sıralamak isteyince bunun şaşırtıcı bir şekilde daha zor olduğunu gördüm. Çünkü PowerShell'in sabit uzunluklu verileri import edecek varsayılan bir yöntem yok. Eğer dosya tipi CSV (virgülle ayrılmış değerler) olsaydı
tarih,isim,yıl
2014-09-12,Cihan,1993
2017-10-01,Zeynep,1992
2013-05-02,Mutlu,1991
bu dosyayı Import-CSV ile import edebilirdik. Dikkat, bu dosyada bir farklılık daha var: sütun başlıkları.
PS C:\> Import-Csv .\veriler.txt
tarih isim yıl
----- ---- ---
2014-09-12 Cihan 1993
2017-10-01 Zeynep 1992
2013-05-02 Mutlu 1991
Burada boru ( | ) operatörü ile çıkışı doğrudan Sort-Object cmdlet'ine gönderebiliriz (kısaca sort).
PS C:\> Import-Csv .\veriler.txt | sort
Bu varsayılan olarak tarih alanına göre sıralar
tarih isim yıl
----- ---- ---
2013-05-02 Mutlu 1991
2017-10-01 Zeynep 1992
2014-09-12 Cihan 1993
İstediğimiz alana göre sıralamak için tırnak içinde alan adını yazıp, sıralamayı büyükten küçüğe yapmak için ise -Descending anahtarını kullanabiliriz.
İlle de powershell ve sabit uzunluklu alanlar diyorsak önce metin dosyasını okuyup bir değişkene atmak gerek:
PS C:\> $metin = Get-Content .\veriler.txt
Daha sonra da bu içeriği CSV'ye uygun şekle çevirmek gerek. veriler.txt dosyasında sütunlar arasında birden fazla boşluk olabildiği için doğrudan boşluğu virgülle değiştirmek işe yaramaz. Bunun için önce her sütunun sadece 1 boşluk ile ayrılmasını sağlamak gerek. Yeterli sayıda şu komutu ard arda kullanmak ilk adım:
PS C:\> $metin = $metin -replace " "," "
yukarıda -replace'ten sonra çift tırnakların arasında 2 boşluk karakteri, ikinci çift tırnakların arasında ise 1 boşluk karakteri var. Sonrasında her boşluğu virgülle değiştirmek gerek:
PS C:\> $metin = $metin -replace " ",","
Daha sonra da bu verilere bir başlık satırı eklemek gerek. Önce bir $csv değişkeni oluşturalım:
PS C:\> $csv = @()
Başlık satırını ekleyelim:
PS C:\> $csv += "Tarih,Isim,Yil"
Sonra buna verilerimizi ekleyelim
PS C:\> $csv += $metin
Nihayetinde de bunu ConvertFrom-CSV ile çevirelim
PS C:\> $csv = $csv | ConvertFrom-Csv
Bu noktada $csv değişkenimiz aynen bir CSV dosyasından aktarılmış gibi uygun formatta olacaktır.
Not: Türkçe karakterler (yıl başlığındaki ı harfi) her zamanki gibi sorun. Güzel gözüksün diye düzelttim.