web-dev-qa-db-ja.com

awkで連想配列を並べ替える

私はawkに次のように入力される連想配列を持っています:

chr_count[$3]++

chr_countsを印刷しようとすると、次のようになります。

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

しかし、当然のことながら、iの順序はまったくソートされていません。 chr_countのソートされたキーを反復処理する簡単な方法はありますか?

20
lonestar21

asortの代わりにasorti(source, destination)を使用して、インデックスを新しい配列に並べ替えます。配列をコピーする必要はありません。

次に、宛先配列をソース配列へのポインターとして使用できます。

あなたの例では、次のように使用します。

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

sortコマンドを使用できます。例えば.

for ( i in data )
 print i ":", data[i]  | "sort"
11
krishna murti

asort()asorti()はgawkに固有であり、awkには不明であることに注意してください。プレーンなawkの場合は、独自のsort()をロールするか、他の場所から取得できます。

8
mr. fixit

これは ドキュメント から直接取得されます:

 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
 }
4
Cascabel

最近この問題に遭遇し、gawkを使用してPROCINFO["sorted_in"]の値を設定して反復順序を制御できることがわかりました。オンラインでPROCINFOを検索して、これに有効な値のリストを見つけ、これにアクセスしましたGNU Awkユーザーガイドページ: https://www.gnu.org/software/gawk /manual/html_node/Controlling-Scanning.html

これは、@{ind|val}_{num|type|str}_{asc|desc}の形式のオプションを次のようにリストします。

  • indキー(インデックス)による並べ替えとval値による並べ替え。
  • num数値による並べ替え、strは文字列による並べ替え、typeは割り当てられたタイプによる並べ替え。
  • 昇順の場合はasc、降順の場合はdesc

私は単に使用しました:

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

そして、出力は値の降順でソートされました。

2
Joe F