![使用 awk 对文件中的每一列单独进行数字排序](https://linux22.com/image/174360/%E4%BD%BF%E7%94%A8%20awk%20%E5%AF%B9%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%AF%8F%E4%B8%80%E5%88%97%E5%8D%95%E7%8B%AC%E8%BF%9B%E8%A1%8C%E6%95%B0%E5%AD%97%E6%8E%92%E5%BA%8F.png)
我正在尝试对一个非常大的文件中的每一列进行单独的数字排序。我需要命令速度快,所以我尝试在 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