Ответы:
С помощью awk
awk '{for (i=1;i<=NF;i++) sum[i]+=$i;}; END{for (i in sum) print "for column "i" is " sum[i];}' FileA
for column 1 is 8
for column 2 is 11
for column 3 is 7
for column 4 is 5
Используйте numsum
для этой задачи и отделите между обработкой данных и выводом результатов.
Установить num-utils
, нам нужноnumsum
sudo apt-get install num-utils
И начать с
numsum -c <your_file_name>
пример
$ cat "File A"
1 2
2 3
4 5 6
1 1 1 5
$ numsum -c "File A"
8 11 7 5
или с вашим желаемым форматом:
$ numsum -c "File A" | awk '{for(i=1;i<=NF;i++) {print "for column "i" is "$i}}'
for column 1 is 8
for column 2 is 11
for column 3 is 7
for column 4 is 5
от man numsum
-c Print out the sum of each column.
примеры из man numsum
EXAMPLES
Add up the 1st, 2nd and 5th columns only.
$ numsum -c -x 1,2,5 columns
15 40 115
Add up the rows of numbers of a file.
$ numsum -r columns
55
60
65
70
75
#!/bin/sh
while read a b c d; do
col1=$((col1 + a))
col2=$((col2 + b))
col3=$((col3 + c))
col4=$((col4 + d))
done < File_A
echo $col1 $col2 $col3 $col4
(( col1 += a ))
и т. Д. Также echo "..."
безопаснее, как иwhile IFS= read -r ...
echo
безопасно использовать таким образом, чтобы отображать числа, $IFS
значения по умолчанию в пробелах, и ожидается, что они будут числами, поэтому нет необходимости иметь обратную косую черту. Единственным недостатком этого ответа является необходимость знать количество столбцов до выполнения.
echo "[...]"
для правильной печати того, что вы не хотите выводить, не имеет смысла.
echo $var
и while read a b c
это работает здесь. Тем не менее, вы привыкнете писать его слабо, и однажды вы получите странные ошибки при обработке более сложного файла. Тогда вы заметите, что цитируете переменные, и использование while IFS= read -r ...
было безопаснее и скажет: «О да, Федорки был прав, я надеюсь, что он мог бы обнять его, чтобы выразить благодарность!».
Судя по комментариям к вашему собственному ответу, вам нужна только сумма по одному столбцу за раз. Если это так, вот не-awk способ сделать это:
cut -d' ' -f3 FileA | grep . | paste -s -d+ | bc
где вы могли бы заменить 3
интересующий вас номер столбца.
Вот однострочный подход к Perl-скрипту. Это основано на использовании -a
флага, который позволяет автоматически разбивать текущую строку с -n
флагом в массив @F
. Все, что нам нужно сделать, это перебрать эти элементы и добавить их к соответствующему индексу в $sum
массиве, таким образом, фактически каждый элемент массива является суммой для каждого соответствующего столбца. Наконец, мы печатаем результат в END
блоке кода.
$ perl -lane '$j=0;foreach $i (@F){$sum[$j]+=$i; $j+=1;}; END{print join("\n",@sum)} ' input.txt
8
11
7
5
В качестве альтернативы приведем полный подход к сценарию Perl. Он основывается на разбиении каждой строки на массив и итерации по каждому элементу в этом массиве, добавляя каждое число к их соответствующей возможности в @sums
массиве. Сценарий распечатывает каждую строку, а затем создает отчет для каждого столбца. Печать каждой строки можно удалить, добавив #
передprintf("%s",$line);
#!/usr/bin/env perl
use strict;
use warnings;
open(my $fh,"<",$ARGV[0]);
my $i = 0;
my @sums;
while(my $line = <$fh>) {
printf("%s",$line);
my @nums = split(" ",$line);
my $j = 0;
foreach my $num (@nums){
$sums[$j] += $num;
$j += 1;
}
}
my $k = 0;
foreach my $sum (@sums){
printf("- column %d sum: %d\n",$k,$sum);
$k+=1;
}
close($fh);
Использование простое chmod +x ./sum_columns.pl && ./sum_columns.pl input.txt
. Например:
$ ./sum_columns_2.pl input.txt
1 2
2 3
4 5 6
1 1 1 5
- column 0 sum: 8
- column 1 sum: 11
- column 2 sum: 7
- column 3 sum: 5
Простое решение:
awk '{sum += $i} END {print sum}' file
Замените i номером столбца, например column1:
awk '{sum += $1} END {print sum}' file
вывод:
8