2010-12-08 1 views
2

Ich habe eine Reihe von Tabellen in folgendem Format:Zellweise Summierung von Tabellen in einem Linux-Shell-Skript

1000 3 0 15 14 
2000 3 0 7 13 
3000 2 3 14 12 
4000 3 1 11 14 
5000 1 1 9 14 
6000 3 1 13 11 
7000 3 0 10 15 

Sie in einfachen Textdateien sind.

Ich möchte diese Dateien in einer neuen Tabelle im gleichen Format zusammenführen, wobei jede Zelle (X, Y) die Summe aller Zellen (X, Y) aus dem ursprünglichen Satz von Tabellen ist. Ein etwas komplizierender Faktor ist, dass die Zahlen aus der ersten Spalte nicht summiert werden sollten, da dies Labels sind.

Ich vermute, dass dies mit AWK getan werden kann, aber ich bin nicht besonders versiert in dieser Sprache und kann keine Lösung im Web finden. Wenn jemand ein anderes Werkzeug vorschlägt, ist das auch in Ordnung.

Ich möchte dies aus einem Bash-Shell-Skript tun.

+1

Geben Sie ein Beispiel für Ihre erwartete Ausgabe an. –

+0

Möchten Sie alle Spalten aus jeder Datei oder jeder Zelle, die zu demselben Label gehört, aus jeder Datei zusammenfassen? Macht das Sinn? :) – jgr

Antwort

2

geben diesem einen Versuch:

#!/usr/bin/awk -f 
{ 
    for (i=2;i<=NF; i++) 
     a[$1,i]+=$i 
    b[$1]=$1 
    if (NF>maxNF) maxNF=NF 
} 

END { 
    n=asort(b,c) 
    for (i=1; i<=n; i++) { 
     printf "%s ", b[c[i]] 
     for (j=2;j<=maxNF;j++) { 
      printf "%d ", a[c[i],j] 
     } 
     print "" 
    } 
} 

Run es wie folgt aus:

./sumcell.awk table1 table2 table3 

oder

./sumcell.awk table* 

Der Ausgang Ihrem Beispiel Eingabe mit zweimal würde wie folgt aussehen:

$ ./sumcell.awk table1 table1 
1000 6 0 30 28 
2000 6 0 14 26 
3000 4 6 28 24 
4000 6 2 22 28 
5000 2 2 18 28 
6000 6 2 26 22 
7000 6 0 20 30 
+0

verwendest du blockquotes? meine Antwort sieht ... mitleidig aus. – jgr

+0

@jgr: Nein, benutzen Sie die Schaltfläche '010101' oder setzen Sie Ihren Code mit vier Leerzeichen ein. Ich habe deinen Beitrag bearbeitet und einen Blick darauf geworfen, was ich getan habe. –

+0

Oh vielen Dank Kumpel! – jgr

1

Summe jeder Zeile, wobei in jeder Zeile mindestens eine numerische Spalte vorausgesetzt wird.

while read line ; do 
    label=($line) 
    printf ${label[0]}' ' ; 
    expr $(
     printf "${label[1]}" 
     for c in "${label[@]:2}" ; do 
      printf ' + '$c 
     done 
    ) 
done < table 

EDIT: Natürlich sah ich nicht den Kommentar über die Kombination basierend auf dem Etikett, so dass dies unvollständig ist.

1
perl -anE'$h{$F[0]}[$_]+=$F[$_]for 1..4}{say$_,"@{$h{$_}}"for sort{$a<=>$b}keys%h' file_1 file_2