这是 Michael Barber 答案的更通用版本,通常适用于任意数量的列和行。
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
请注意,您的示例输入数据会产生我显示的输出,其中包含完整的数据。另请注意,迈克尔的回答仅输出您的示例输出包含的不完整内容。
编辑:
这是一个不需要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")
}
}'
它将以不可预知的顺序打印名称。