2010-03-16 16 views
16

Mam tablicę asocjacyjną w awk, który pobiera zaludnionych tak:Sortuj tablica asocjacyjna w awk

chr_count[$3]++ 

Kiedy próbuję wydrukować mój chr_counts używam to:

for (i in chr_count) { 
    print i,":",chr_count[i]; 
} 

Ale nie co zaskakujące, kolejność i nie jest w żaden sposób sortowana. Czy istnieje łatwy sposób na powtórzenie sortowanych kluczy od chr_count?

+2

Zobacz http://stackoverflow.com/a/5345056/69663 - jeśli masz gawk 4, 'PROCINFO [" sorted_in "] =" @val_num_asc "itp. Są bardzo proste w użyciu. Instrukcja pokazuje wiele różnych opcji, jeśli chcesz maleć/rosnąco, według wartości/klucza, numerycznie/w sposób ciągły, własnej funkcji itp: https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning – unhammer

Odpowiedz

22

Zamiast ASORT, użyj asorti(source, destination) który sortuje indeksy do nowej tablicy i nie będzie musiał skopiować tablicę.

Następnie można użyć tablicy docelowej jako wskaźników do tablicy źródłowej.

Dla przykładu, by go używać tak:

n=asorti(chr_count, sorted) 
for (i=1; i<=n; i++) { 
     print sorted[i] " : " chr_count[sorted[i]] 
} 
+0

Wow, całkowicie o tym zapomniałem pomimo przeczytania tuż obok w dokumentach. To zdecydowanie lepsza odpowiedź. – Cascabel

+0

+1 Genialny !!! –

+1

'asorti' nie działa z nawk-20121220-2.fc20.x86_64. –

4

ta jest pobierana bezpośrednio z the documentation:

populate the array data 
# copy indices 
j = 1 
for (i in data) { 
    ind[j] = i # index value becomes element value 
    j++ 
} 
n = asort(ind) # index values are now sorted 
for (i = 1; i <= n; i++) { 
    do something with ind[i]   Work with sorted indices directly 
    ... 
    do something with data[ind[i]]  Access original array via sorted indices 
} 
+0

Uważaj, to rozwiązanie jest wadliwe, ponieważ kończy się utratą kluczy, które mają takie same wartości w oryginalnej tablicy. Przyjęte rozwiązanie z tego innego wątku ma pomysł, jak obejść ten problem: http://stackoverflow.com/a/5345056/95750 – haridsv

+1

@haridsv Nie, nie sądzę.To pytanie dotyczy sortowania za pomocą kluczy, a nie wartości i nie może być dwóch wartości dla tego samego klucza, więc nie ma tu problemu. Innym pytaniem, które powinieneś wskazać, jest sortowanie według wartości (które w rzeczywistości mogą nie być różne), więc jeśli spróbujesz użyć tego kodu, będzie to problem. Ale to nie jest wadliwe, jeśli używasz go do tego, do czego jest napisany. – Cascabel

+0

Przeprosiny .. błędnie odczytałem kod indeksujący jako "przerzucanie" kluczy/wartości, ale po ponownym przeczytaniu tego, zauważyłem, że używasz ciągle rosnącej liczby jako indeksu, a nie oryginalnej wartości. Dziękuję, że wróciłeś i wyjaśniłeś to. – haridsv

6

Zauważ, że asort() i asorti() są specyficzne dla gawk, a nie są znane do awk. W przypadku zwykłego awk możesz przetasować swój własny sort() lub zdobyć go gdzie indziej.

11

można użyć polecenia sort. na przykład

for (i in data) 
print i ":", data[i] | "sort" 
0

Niedawno natknąłem się na ten problem i okazało się, że z gawk mogę ustawić wartość PROCINFO["sorted_in"] kontrolować iteracji zamówienia. Znalazłem listę poprawnych wartości to wyszukując PROCINFO online i wylądował na Guide użytkownika GNU awk stronie: https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

Lista opcji formie @{key|val}_{num|type|str}_{asc|desc} z:

  • key sortowanie przez klucz i val sortowanie według wartości.
  • num sortowanie numerycznie, str według ciągu znaków i type według przypisanego typu.
  • asc dla rosnącej kolejności i desc dla malejącej kolejności.

po prostu stosować:

PROCINFO["sorted_in"] = "@val_num_desc" 
for (i in map) print i, map[i] 

a wyjście było sortowane w kolejności malejącej wartości.