awkを使用してファイル内の各列を個別に数値で並べ替える

awkを使用してファイル内の各列を個別に数値で並べ替える

非常に大きなファイルでは、各列を個別に数値で並べ替えようとしています。すばやく命令が必要なので、awk命令にしてみたいと思います。

入力例:

1,4,2,7,4
9,2,1,1,1
3,9,9,2,2
5,7,7,8,8

出力例:

1,2,1,1,1
3,4,2,2,2
5,7,7,7,4
9,9,9,8,8

私はそれを行うことをしました(しかしそれは私に必要な強力なawkコマンドではありません):

for i in $(seq $NumberOfColumns); do 
  SortedMatrix=$(paste <(echo "$SortedMatrix") <(awk -F ',' -v x=$i '{print $x}' File | sort -nr) -d ,)
done

しかし、遅い!
私はawkでこれを試してみましたが、ほぼ似ていると思います。

SortedMatrix=$(awk -F ',' 'NR==FNR {for (i=1;i<=NF;i++) print|"sort -nr"}' File)

ただし、列(ただ長い列)は出力されません。なぜそれを行うのか理解していますが、修正方法がわかりません。 awkで貼り付けを使用するつもりですが、実装方法がわかりません。それ。

awkでこれを行う方法を知っている人はいますか?どんな助けや案内も大いに感謝します。

答え1

単一のGNU awkでこれを行うことができます。

gawk -F ',' '
    {
        for(i=1;i<=NF;i++){matrix[i][NR]=$i}
    }
    END{
        for(i=1;i<=NF;i++){asort(matrix[i])}
        for(j=1;j<=NR;j++){
            for(i=1;i<NF;i++){
                printf "%s,",matrix[i][j]
            }
            print matrix[i][j]
        }
    }
' file
  • for(i=1;i<=NF;i++){matrix[i][NR]=$i}

多次元配列(GNU拡張)は、列と行の数を含むようにmatrix埋められます。matrix[i][j]ij

  • for(i=1;i<=NF;i++){asort(matrix[i])}

各列を並べ替えます(GNU拡張)。

  • ついに

    for(j=1;j<=NR;j++){
        for(i=1;i<NF;i++){
            printf "%s,",matrix[i][j]
        }
        print matrix[i][j]
    }
    

各行に対して一連のa[1],、、、a[2],...、a[NF-1],を印刷します。a[NF]\n

答え2

使用python:

python3 -c 'import sys
L = [] 
with open(sys.argv[1]) as fh:
  L = [line.rstrip("\n").split(",") for line in fh] 
print(*[",".join(j) for j in zip(*[sorted(i,key=int) for i in zip(*L)])],sep="\n")
' file

リストのリスト(行列)にファイルをロードします。 L.

組み込みのzipを使用してデータを転置します。

転置行列の行を数値的にソートします。

もう一度移動して1行ずつ印刷します。

出力:

1,2,1,1,1
3,4,2,2,2
5,7,7,7,4
9,9,9,8,8

関連情報