2010-12-08 46 views
2

J'ai une série de tableaux dans le format suivant:sommation cellulaire des tables dans sage un script shell linux

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 

Ils sont dans des fichiers texte simples. Je veux fusionner ces fichiers dans une nouvelle table dans le même format, où chaque cellule (X, Y) est la somme de toutes les cellules (X, Y) de l'ensemble des tables d'origine. Un facteur légèrement compliquant est que les nombres de la première colonne ne doivent pas être additionnés, puisque ce sont des étiquettes.

Je suppose que cela peut être fait avec AWK, mais je ne suis pas particulièrement versé dans ce langage et je ne trouve pas de solution sur le web. Si quelqu'un suggère un autre outil, c'est aussi bien. Je veux faire cela à partir d'un script shell bash.

+1

Veuillez fournir un exemple de votre résultat attendu. –

+0

voulez-vous résumer toutes les colonnes de chaque fichier ou chaque cellule appartenant à la même étiquette de chaque fichier? Est-ce que ça a du sens? :) – jgr

Répondre

2

pour cette solution:

#!/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 "" 
    } 
} 

Exécuter comme ceci:

./sumcell.awk table1 table2 table3 

ou

./sumcell.awk table* 

La sortie en utilisant deux fois votre entrée exemple ressemblerait à ceci:

$ ./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

est-ce que vous utilisez des blockquotes? ma réponse a l'air ... pitoyable. – jgr

+0

@jgr: non, utilisez le bouton '010101' ou indentez votre code en utilisant quatre espaces. J'ai édité votre post, regardez ce que j'ai fait. –

+0

oh merci beaucoup mec! – jgr

1

Somme chaque ligne, en supposant au moins une colonne numérique sur chaque ligne.

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: Bien sûr, je n'ai pas vu le commentaire sur la combinaison basée sur l'étiquette, donc c'est incomplet.

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