2017-05-15 2 views
0

Ich habe eine Datei mit Informationen in 3 Spalten getrennt. Die erste Spalte repräsentiert die Kategorien, die die obere Zeile der Matrix füllen, die zweite Spalte repräsentiert die Kategorien, die in der ersten Spalte der Matrix stehen. Die dritte Zeile repräsentiert die Werte, die den Großteil der Matrix füllen. Spalten 1 und 2 der Originaldatei können umgekehrt werden, es macht keinen Unterschied.Drehen Sie Datei von 3 Spalten in eine Matrix

Die Datei sieht wie folgt aus

Category1 type1 + 
Category1 type2 - 
Category1 type3 + 
Category2 type1 + 
Category2 type2 + 
Category2 type3 + 
Category3 type1 + 
Category3 type2 - 
Category3 type3 - 

ich es in eine Matrix drehen möchten, wie diese awk wird ich denke

Category1 Category2 Category3 
type1 + + + 
type2 - + - 
type3 + + - 

sieht es wahrscheinlich tun, das tue ich einfach nicht wissen, wie man awk das macht

+0

Betreffend die Eingabedaten: Sind die Spalten durch Tabulatoren getrennt oder durch Leerzeichen getrennt? Wie sollte es in Bezug auf die Produktion sein? – Scheff

+0

@Scheff Alles ist Tab getrennt – Jacob

+0

Aha. Ich werde bald eine Lösung schicken. (Es funktioniert derzeit mit Leerzeichen für Eingabetrennung und Tabs für die Ausgabetrennung.) – Scheff

Antwort

1

awk zur Rettung!

awk 'BEGIN {FS=OFS="\t"} 
      {col[$1]; row[$2]; val[$2,$1]=$3} 
    END {for(c in col) printf "%s", OFS c; print ""; 
      for(r in row) 
       {printf "%s", r; 
       for(c in col) printf "%s", OFS val[r,c] 
       print ""}}' file 

     Category1  Category2  Category3 
type1 +  +  + 
type2 -  +  - 
type3 +  +  - 
+0

Ich denke, das ist an dem Punkt, wo es besser wäre, es in ein Skript zu schreiben, als ein "Einliner". – 123

+0

Ich stimme nicht zu ... – karakfa

1

Dies ist eine Lösung basierend auf GNU awk. Ich betone dies, weil mehrdimensionale Arrays (die für eine bequeme Lösung erhalten werden) ein für GNU awk spezifisches Merkmal sind.

Mein Skript table2matrix.awk:

# collect values 
{ 
    # category=$1 ; type=$2 ; value=$3 
    if (!($1 in categories)) { categories[$1] } 
    types[$2][$1] = $3 
} 
# output of values 
END { 
    # print col. header 
    for (category in categories) { printf("\t%s", category); } 
    print "" 
    # print rows 
    for (type in types) { 
    printf("%s", type); 
    for (category in categories) { 
     printf("\t%s", types[type][category]); 
    } 
    print "" 
    } 
} 

Beispielsitzung:

$ cat >table.txt <<EOF 
> Category1 type1 + 
> Category1 type2 - 
> Category1 type3 + 
> Category2 type1 + 
> Category2 type2 + 
> Category2 type3 + 
> Category3 type1 + 
> Category3 type2 - 
> Category3 type3 - 
> EOF 

$ awk -f table2matrix.awk table.txt 
     Category1  Category2  Category3 
type1 +  +  + 
type2 -  +  - 
type3 +  +  - 

$ cat table.txt | sed $'s/ /\t/g' >table-tabs.txt 

$ awk -f table2matrix.awk table-tabs.txt 
     Category1  Category2  Category3 
type1 +  +  + 
type2 -  +  - 
type3 +  +  - 

$ cat >table-sorted.txt <<EOF 
> Category1 type1 + 
> Category1 type3 + 
> Category2 type1 + 
> Category2 type2 + 
> Category2 type3 + 
> Category3 type1 + 
> Category1 type2 - 
> Category3 type2 - 
> Category3 type3 - 
> EOF 

$ awk -f table2matrix.awk table-sorted.txt 
     Category1  Category2  Category3 
type1 +  +  + 
type2 -  +  - 
type3 +  +  - 

$ tac table.txt >table-reverse.txt 

$ awk -f table2matrix.awk table-reverse.txt 
     Category1  Category2  Category3 
type1 +  +  + 
type2 -  +  - 
type3 +  +  - 

$ grep '+' table.txt >table-incompl.txt 

$ awk -f table2matrix.awk table-incompl.txt 
     Category1  Category2  Category3 
type1 +  +  + 
type2   + 
type3 +  + 

$ 

table.txt ist Leerzeichen getrennt (von Web-Browser Kopieren/Einfügen), table-tabs.txttable.txt mit Folgen von Leerzeichen durch Tabulatoren ersetzt ist.

Wie aus dem Skript hervorgeht (aber nicht aus dem Codebeispiel im Webbrowser), ist die Ausgabe tabulatorgetrennt.

Nachdem ich einige Variationen der ursprünglichen Beispieleingabe getestet hatte, reparierte ich mein awk-Skript. Es wurde ein bisschen kürzer und viel ähnlicher als die andere Lösung von karafka ...

Verwandte Themen