2012-04-28 4 views
1

Я хотел бы получить помощь в работе, но я действительно не знаю, как добраться до нее. Я должен сделать матрицу расстояний, froma текст 3 столбца, который выглядит следующим образом:awk distance matrix

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 

Выход должен быть квадратный shapet «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, и он, наконец, читает все поля, но в разных выравниваниях.

ответ

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") 
    } 
}' 
+0

спасибо! Это была большая помощь :) – JohnnnnnY

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 

Обратите внимание, что образцы входных данных дает выход я показал, который включает в себя полные данные в нем. Обратите внимание также, что ответ Майкла выводит только то, что включает в себя ваш выборка, который является неполным.

Edit:

Вот версия, которая не требует 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") 
    } 
}' 

Он будет печатать имена в непредсказуемом порядке.

+0

Увидели это немного позже, но thx для этой версии тоже :) – JohnnnnnY

+0

только probem теперь пишет «function sort never defined» – JohnnnnnY

+0

@ JánosBalázs: Какая версия AWK? Обратите внимание, что это должно быть «asort» (с «a»). Если ваша версия не включает функцию 'asort()', одна вещь, которую вы можете сделать, это изменить строку 'num = asort (имена)' to 'for (i в именах) {num ++}' (так как ваша 'length () 'функция, вероятно, не примет массив в качестве аргумента.Это должно работать, но имена не будут выводиться в предсказуемом порядке. К сожалению,' asort() 'специфичен для GNU AWK (' gawk'). –