awk距离矩阵

时间:2012-04-28 13:03:29

标签: matrix awk distance

我想得到一些工作的帮助,但我真的不知道如何去做。我必须制作一个3列文本的距离矩阵,如下所示:

AN51 AN50 88
AN52 AN50 167
AN52 AN51 125
AN53 AN50 81
AN53 AN51 93
AN53 AN52 170
AN54 AN50 120
AN54 AN51 119
AN54 AN52 117
AN54 AN53 66 

输出必须是方形的“2d”矩阵

    AN50  AN51  AN52 AN53
AN50 0     88   167   81
AN51 88    0    125   93
AN52 167   125   0    170
AN53 81    93   170    0

我尝试使用$ 0从文件中读取,最后读取所有字段,但不同的对齐方式。

2 个答案:

答案 0 :(得分:3)

awk '
{ 
  matrix[$1,$2] = $3
  matrix[$2,$1] = $3 
} 
END { 
  printf("\tAN50\tAN51\tAN52\tAN53\n")
  for (n=0;n<4;n++) { 
    printf("AN5%d\t", n)
    for (m=0; m<4; m++) { 
      printf("%d\t", matrix["AN5"n,"AN5"m]) 
    } 
    printf("\n") 
  } 
}'

答案 1 :(得分:3)

这是迈克尔·巴伯答案的更为通用的版本,通常可以使用任意数量的列和行。

awk '
BEGIN {
    OFS = "\t"
}
{
    matrix[$1,$2] = $3
    matrix[$2,$1] = $3
    names[$1] = $1
    names[$2] = $2
}
END {
    num = asort(names)
    for (i = 1; i <= num; i++) {
        printf("%s%s", OFS, names[i])
    }
    printf("\n")
    for (i = 1; i <= num; i++) {
        printf("%s", names[i])
        for (j = 1; j <= num; j++) {
            printf("%s%4d", OFS, matrix[names[i], names[j]])
        }
        printf("\n")
    }
}'

示例输出:

        AN50    AN51    AN52    AN53    AN54
AN50       0      88     167      81     120
AN51      88       0     125      93     119
AN52     167     125       0     170     117
AN53      81      93     170       0      66
AN54     120     119     117      66       0

请注意,您的示例输入数据会生成我显示的输出,其中包含完整的数据。另请注意,Michael的答案仅输出您的示例输出包含的内容不完整。

修改

这是一个不需要asort()的版本,应该适用于非GNU版本的AWK:

awk '
BEGIN {
    OFS = "\t"
}
{
    matrix[$1,$2] = $3
    matrix[$2,$1] = $3
    names[$1] = $1
    names[$2] = $2
}
END {
    for (i in names) {
        printf("%s%s", OFS, i)
    }
    printf("\n")
    for (i in names) {
        printf("%s", i)
        for (j in names) {
            printf("%s%4d", OFS, matrix[i,j])
        }
        printf("\n")
    }
}'

它将以不可预测的顺序打印名称。