Unix sıralama kullanarak özel sıralama nasıl yapılır?


8

Birden çok sütunlu virgülle ayrılmış bir dosyayı sıralamak için unix sort kullanıyorum. Şimdiye kadar, bu verileri sayısal olarak veya alfabetik sıraya göre sıralamak için mükemmel bir şekilde çalıştı:

Herhangi bir sıralamadan önce örnek dosya:

C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

Dosyayı sırala: $ sort -t ',' -k 2,2 -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

Sıralanan sonuç:

A,Bahamas,Bahamas,Nassau,f,2
A,Canada,QC,Montreal,f,2
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1

Sorun şu: 2. sütunu özel bir sıralamaya göre sıralamak istiyorum, yani önce Amerika Birleşik Devletleri'ni sonra Kanada’yı sonra Bahamalar’ı istiyorum:

İstenilen sıralama:

A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

Unix sorti uygulayabileceği özel bir sıralama düzenini geçmenin bir yolu var mı? Gibi bir şey: $ sort -t ',' -k 2,2:'United States, Canada, Bahamas' -k 3,3 -k 4,4 -k 5,5r -k 6,6nr tmp.csv

Teşekkürler!


3
Bu üç değer için, ters alfabetik sıra istersiniz. Genel durum için, adları bir sıralama düzeni numarasıyla eşlemeniz ve ardından sıralama düzeni numarasını kullanarak sıralamanız gerekir. Veya bir betik dili için gitmek ... Bir olasılık join komut, ancak çok fazla sıralama ile sona erebilir - giriş dosyaları join tek bir sıraya göre sıralanmalı ve sonra sort Verileri farklı bir sıraya koymak için (ve bir sıralama sonrası adımı olarak sıralama düzeni sütununu kaybederek) tekrar.
Jonathan Leffler

Örnek girişinizde, olmamalı t yerine f son satırda
Lev Levitsky

Lev: evet, iyi yakalayış. Benim hatam; Çok fazla kesme ve yapıştırma (gerçek veri setim çok daha büyük ve yanlışlıkla yanlış satırları yakaladım).

Verilerinizi eşleştirmek için cevabı güncelledim.
Lev Levitsky

Yanıtlar:


7

Diğer cevap ve yorum ise genel olarak soruyu cevaplar, işte bir uygulamanın nasıl göründüğü:

$ cat order
Bahamas,3
Canada,2
United States,1

$ cat data
C,United States,WA,Tacoma,f,1
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2
A,United States,NY,New York,f,1

$ sort -t, -k2 data | join -t, -11 -22 order - | sort -t, -k2n -k4,5 -k6r -k7nr | cut -d, -f 3,1,4-7
A,United States,MA,Boston,f,0
B,United States,NY,New York,f,5
A,United States,NY,New York,f,1
C,United States,WA,Tacoma,f,1
A,Canada,QC,Montreal,f,2
A,Bahamas,Bahamas,Nassau,f,2

Müthiş, yardımlarınız için teşekkürler. Bu mükemmel çalıştı!

@jewelia Bir kez daha geliştirildi, sed burada gerçekten gerekli değildi.
Lev Levitsky

1

Bunu yapamazsın çeşit . Bu noktada, gerçekten ulaşıyor olmalısınız awk / perl / senin dil-of-seçim . Yine de geçebilirsiniz. Örneğin, "Amerika Birleşik Devletleri" ni 0, "Kanada" ı 1 ve "Bahamalar" ı 2 olarak değiştirmek için sed kullanabilirsiniz, sonra bu sütuna karşı sayısal bir sıralama yapabilir, sonra geri kaldırabilirsiniz. Veya "Amerika Birleşik Devletleri" ni "Amerika Birleşik Devletleri, 0" vb olarak değiştirin, fazladan sütuna göre sıralayın ve atın.


0

Az önce yazdım csort adlı bir yardımcı Bunu kolaylaştırmak için. Her bir satırı, alt dize veya satır içindeki normal ifade eşleşmelerini temel alarak seçtiğiniz bir değere ön ekler:

$ csort -t, '2=United States' X 2=Canada Y 2=Bahamas Z < tmp.csv | \
sort -t, -k1,1 -k3,3 -k4,4 -k5,5 -k6,6r -k7,7nr
X,A,United States,MA,Boston,f,0
X,B,United States,NY,New York,f,5
X,A,United States,NY,New York,f,1
X,C,United States,WA,Tacoma,f,1
Y,A,Canada,QC,Montreal,f,2
Z,A,Bahamas,Bahamas,Nassau,f,2

2=STR gösterim, "ikinci alan eşittir ise eşleşme demektir" STR ".

Daha sonra isteğe bağlı olarak çıkış üzerinden çıkış yapabilirsiniz. cut -c3- öneki kaldırmak için.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.