2012-04-04 10 views
4

Ich versuche, eine wirklich lange Datei zu transponieren, und ich bin besorgt, dass es nicht vollständig umgesetzt wird.transpose Spalte und Zeilen mit gawk

sieht Meine Daten etwas wie folgt aus:

Thisisalongstring12345678 1 AB abc 937 4.320194 
Thisisalongstring12345678 1 AB efg 549 0.767828 
Thisisalongstring12345678 1 AB hi 346 -4.903441 
Thisisalongstring12345678 1 AB jk 193 7.317946 

ich meine Daten so aussehen wollen:

Thisisalongstring12345678 Thisisalongstring12345678 Thisisalongstring12345678 Thisisalongstring12345678 
1       1       1       1 
AB      AB      AB      AB 
abc      efg      hi      jk 
937      549      346      193 
4.320194     0.767828     -4.903441     7.317946 

Würde die Länge der ersten Zeichenfolge beweisen ein Problem sein? Meine Datei ist viel länger als diese ca. 2000 Zeilen lang. Ist es auch möglich, den Namen der ersten Saite in Thisis234 zu ändern und dann zu transponieren?

+0

Wenn Sie bereit sind, Zeilen von 20.000 * 25 Zeichen (oder so) pro Spalte (also 100 KiB oder so pro Zeile) zu akzeptieren, und die Anwendungen, mit denen Sie arbeiten, sind auch die Chancen, dass 'gawk 'wird damit auch in Ordnung sein. Ja, Sie können die langen Namen abschneiden; Ermitteln des Algorithmus und Anwendung auf die Ausgabe oder während der Eingabe. –

Antwort

7

Ich sehe nicht, warum es nicht sein wird - es sei denn, Sie haben nicht genug Speicher. Versuchen Sie es mit den folgenden Punkten und sehen Sie, ob Sie Probleme haben.

Eingang:

$ cat inf.txt 
a b c d 
1 2 3 4 
. , + - 
A B C D 

awk-Programm:

$ cat mkt.sh 
awk ' 
{ 
    for(c = 1; c <= NF; c++) { 
    a[c, NR] = $c 
    } 
    if(max_nf < NF) { 
    max_nf = NF 
    } 
} 
END { 
    for(r = 1; r <= NR; r++) { 
    for(c = 1; c <= max_nf; c++) { 
     printf("%s ", a[r, c]) 
    } 
    print "" 
    } 
} 
' inf.txt 

Run:

$ ./mkt.sh 
a 1 . A 
b 2 , B 
c 3 + C 
d 4 - D 

Credits:

Hoffe, das hilft.

+0

Ähnlich wie [Befehlszeilenpivot] (http://stackoverflow.com/questions/9475806/command-line-pivot) – ghoti

+0

@ghoti Einverstanden, es ist ein ähnliches Thema, andere Ansatz - gut für OP, Optionen zu haben! –

3

Ich versuchte icyrock.com Antwort, fand aber, dass ich ändern musste:

for(r = 1; r <= NR; r++) { 
    for(c = 1; c <= max_nf; c++) { 

zu

for(r = 1; r <= max_nf; r++) { 
    for(c = 1; c <= NR; c++) { 

die NR Spalten und max_nf Zeilen zu erhalten. So icyrock Code wird:

$ cat mkt.sh 
awk ' 
{ 
    for(c = 1; c <= NF; c++) { 
    a[c, NR] = $c 
    } 
    if(max_nf < NF) { 
    max_nf = NF 
    } 
} 
END { 
    for(r = 1; r <= max_nf; r++) { 
    for(c = 1; c <= NR; c++) { 
     printf("%s ", a[r, c]) 
    } 
    print "" 
    } 
} 
' inf.txt 

Wenn Sie das nicht tun und verwenden Sie einen asymmetrischen Eingang, wie:

a b c d 
1 2 3 4 
. , + - 

Sie erhalten:

a 1 . 
b 2 , 
c 3 + 

also noch 3 Zeilen und 4 Spalten (die letzte davon ist leer).

0

Für @ ScubaFishi und @ icyrock Code:

"if (max_nf < NF)" scheint nicht notwendig. Ich habe es gelöscht und der Code funktioniert einwandfrei.