2013-02-19 3 views
2

У меня есть файл в следующем форматекак суммировать каждый столбец в файл с помощью Баша

id_1,1,0,2,3,lable1 
id_2,3,2,2,1,lable1 
id_3,5,1,7,6,lable1 

и я хочу просуммировать каждую колонку (у меня есть более 300 столбцов)

9,3,11,10,lable1 

как я могу это сделать, используя bash. Я пробовал использовать то, что описано here, но не работал.

ответ

1

Если суммы должны быть сгруппированы по метке в последнем столбце, вы можете попробовать это:

awk -F, ' 
    { 
    L[$NF] 
    for(i=2; i<NF; i++) T[$NF,i]+=$i 
    } 
    END{ 
    for(i in L){ 
     s=i 
     for(j=NF-1; j>1; j--) s=T[i,j] FS s 
     print s 
    } 
    } 
' file 

Если метки в последнем столбце сортируются, то вы можете попробовать без массивов и экономии памяти:

awk -F, ' 
    function labelsum(){ 
    s=p 
    for(i=NF-1; i>1; i--) s=T[i] FS s 
    print s 
    split(x,T) 
    } 
    p!=$NF{ 
    if(p) labelsum() 
    p=$NF 
    } 
    { 
    for(i=2; i<NF; i++) T[i]+=$i 
    } 
    END { 
    labelsum() 
    } 
' file 
+0

Спасибо, ваше решение добавило преимущество использования нескольких файлов в файле – Roola

6

Использование awk:

$ awk -F, '{for (i=2;i<NF;i++)a[i]+=$i}END{for (i=2;i<NF;i++) printf a[i]",";print $NF}' file 
9,3,11,10,lable1 

Это будет печатать сумму каждого столбца (с = 2 .. я = п-1) в разделенных запятыми файла с последующим значение последнего столбца из последний ряд (т.е. lable1).

+0

Спасибо, что работал отлично – Roola

1

Вот Perl один вкладыш:

<file perl -lanF, -E 'for (0 .. $#F) { $sums{ $_ } += $F[ $_ ]; } END { say join ",", map { $sums{ $_ } } sort keys %sums; }' 

Он будет делать только суммы, так что первый и последний столбец в вашем примере будет 0.

Эта версия будет следовать ваш пример вывода:

<file perl -lanF, -E 'for (1 .. $#F - 1) { $sums{ $_ } += $F[ $_ ]; } END { $sums{ $#F } = $F[ -1 ]; say join ",", map { $sums{ $_ } } sort keys %sums; }' 
+0

Спасибо это один и решил его – Roola

1

модифицированная версия, основанная на решении вы связаны:

#!/bin/bash 

colnum=6 
filename="temp" 

for ((i=2;i<$colnum;++i)) 
do 
    sum=$(cut -d ',' -f $i $filename | paste -sd+ | bc) 
    echo -n $sum',' 
done 
head -1 $filename | cut -d ',' -f $colnum 
0

Чистый раствор Баш:

#!/usr/bin/bash 


while IFS=, read -a arr 
do 
     for((i=1;i<${#arr[*]}-1;i++)) 
     do 
       ((farr[$i]=${farr[$i]}+${arr[$i]})) 
     done 
     farr[$i]=${arr[$i]} 
done < file 
(IFS=,;echo "${farr[*]}") 
Смежные вопросы