テキストファイルの列を並べ替える方法は?

テキストファイルの列を並べ替える方法は?
Month   Name  Marks  
2016-10 Sam   58  
2016-09 Sam   77  
2016-10 John  64  
2016-09 John  47  
2016-10 Mark  71  
2016-09 Mark  38  
2016-10 Steve 83  
2016-09 Steve 39  

私は最初の列に月があり、2番目の列に各学生のスコアがあるデータベースからこのデータを取得しています。さて、最初の列に名前があり、2番目の列に2016-10タグがあり、3番目の列に2016-09タグがあるように編集したいと思います。

ベストアンサー1

入力データが「grades」というファイルにあるとし、次のことを試してください。

$ awk 'BEGIN{ PROCINFO["sorted_in"]="@ind_str_desc"} NR==1{next} {m[$1]; n[$2]; g[$2,$1]=$3} END{for (name in n) {printf "%s",name; for (month in m) printf " %s",g[name,month]; print""}}' grades | column -t
Steve  83  39
Sam    58  77
Mark   71  38
John   64  47

出力は学生ごとに 1 行で、成績は月ごとに降順でソートされます。

コードを複数行にわたって分散したい場合:

gawk '
    BEGIN{ PROCINFO["sorted_in"]="@ind_str_desc"}
    NR==1{
        next
    }

    {
        m[$1]
        n[$2]
        g[$2,$1]=$3
    }

    END{
        for (name in n) {
            printf "%s",name
            for (month in m)
                printf " %s", g[name,month]
                print""
        }
    }

    ' grades | column -t

どのように動作しますか?

  • BEGIN{ PROCINFO["sorted_in"]="@ind_str_desc"}

    これは、配列がインデックスごとにソートされることを望んでいることをawkに伝えます。これがGNUの特徴です。

  • NR==1{next}

    これはawkに最初の行をスキップするように指示します。出力ファイルにヘッダーを追加するには、ここで行うことができます。

  • m[$1]

    これは、awkに連想配列に現在の月のエントリを追加するように指示しますm。入力にどの月があるかを追跡するためにのみ使用されるため、値を割り当てる必要はありません。

  • n[$2]

    これは、連想配列に生徒名のエントリを追加するようにawkに指示しますn。入力にどの月があるかを追跡するためにのみ使用されるため、値を割り当てる必要はありません。

  • g[$2,$1]=$3

    これにより、連想配列の生徒名、月キーの下の値として成績が割り当てられますg

  • END{for (name in n) {printf "%s",name; for (month in m) printf " %s",g[name,month]; print""}}

    ファイルの終わりに達すると、各生徒のすべての名前と成績を印刷します。

  • column -t

    このオプションのステップは出力をきれいにします。

おすすめ記事