我想得到一些工作的帮助,但我真的不知道如何去做。我必须制作一个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从文件中读取,最后读取所有字段,但不同的对齐方式。
答案 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")
}
}'
它将以不可预测的顺序打印名称。