使用 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]包含列数i、行数j

  • 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,2,1,1,1
3,4,2,2,2
5,7,7,7,4
9,9,9,8,8

相关内容