Sıralama sıralama düzeni bilmiyorsa GNU sıralama kararlı sıralama


18

İki sütunlu bir dosya var; dosya zaten sütun 1'de istediğim şekilde sıralanır. Her sütun 1 kategorisi içinde sütun 2'de sıralamak istiyorum. Ancak, sortsütun 1'in sıralama düzenini anlamıyor.

Normal yol (burada yığındaki benzer sorulardan) şu olurdu:

sort --stable -k1,1 -k2,2n

Ancak k1'deki sıralamayı belirleyemiyorum, çünkü keyfi.

Örnek girdi:

C 2
C 1
A 2
A 1
B 2 
B 1

ve çıktı:

C 1
C 2
A 1
A 2
B 1 
B 2

Yanıtlar:


20

Her blok için yeni bir sıralama başlatmak için awk'yi kullanabilirsiniz:

% awk -v cmd="sort -k2,2" '$1 != prev {close(cmd); prev=$1} {print | cmd}' foo
C 1
C 2
A 1
A 2
B 1
B 2
  • $1 != prev {close(cmd); prev=$1} - kaydedilen değer farklı olduğunda, yeni bir bloğumuz var, bu yüzden daha önce başlatılmış olanları kapatıyoruz sort
  • {print | "sort -k2,2"}'sortzaten çalışmıyorsa çıkışı başlatır (awk başlattığı komutları takip edebilir)

2
awk gerçekten inanılmaz. Bunu beklediğimden çok daha fazla sevdim, ki bu bir garip süsle-sırala-dekore et!
Evan Benn

Bunun cevabını diğer cevapla karşılaştırmaya çalıştım, neden daha fazla kaynak kullandığından emin değilim ... Herhangi bir fikir? gist.github.com/EvanTheB/5b64eafb84eeaf51c289295ac06e1b0b
Evan Benn

Ortalama kaç koşu yaptınız?
muru

Ortalama almadım, ancak tekrarlayıp araştırırken tutarlı çalışma süreleri görüyorum.
Evan Benn

İşte araştırmak istiyorsanız kullandığım şeye benzer bir dosya:seq 30 | xargs -L1 bash -cs 'yes $1 | head -1000000 | paste - <(seq 1000000) | shuf' bash
Evan Benn

12

Bir kullanabilirsiniz Schwartzian dönüşümü (bu temelde daha süslemeleri-sort-undecorate bir yorumda ima yaklaşım, ancak büyük olasılıkla daha fazla ölçülebilir MURU en ince cevap nedeniyle tek kullanmadan sortkullanarak - katına aksine çağırma) awkbir önek sütun ekleyin ilk sütunda değer değişikliği olan artışlarla, önek sütununa ve ardından "ikinci" sütuna (sıra konumu 3önek sütununun varlığı nedeniyle geçici olarak kaymış olan) göre sıralayın ve son olarak önek sütunundan kurtulun

awk '{print ($1 in a? c+0: ++c)"\t" $0; a[$1]}' file | sort -k1,1n  -k3,3 | cut -f 2-

Şaşırdım, ama haklısın, bu diğer cevaptan daha hızlıydı! 100 milyon satır dosyamda 3 dakika vs 2 dakika (~ 30 uniq ilk sütun).
Evan Benn

1
İlk sütundaki benzersiz anahtar dizisini tutmanıza gerek yoktur. Mevcut satırın ilk sütununu bir önceki sütunla karşılaştırmak yeterli olmalı diye düşünüyorum.
Kusalananda

Gibi bir şey awk -v OFS="\t" '$1 != prev { key++ } { print key, $0; prev = $1 }(denenmemiş).
Kusalananda
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.