Как добавить каждый вывод awk

Как добавить каждый вывод awk

Как бы вы выполнили сложение выводимых данных каждой строки из awk?

Например

cat foo | awk '{print $1}
42
42
42

Я ищу ответ на 42+42+42 (126).

Я пытаюсь написать цикл for, чтобы сделать это, но должен быть более простой способ.

#Not Working, and way too complex
cat foo |awk  '{ print $1 }'|for i in $1 do; foo=$(( foo+$(i) )) done| echo $foo

Я мог бы передать данные по конвейеру, wc -lно это только выведет количество строк, а не оценит их.

Как мне оценить каждую строку из awk?

решение1

Базовый подход, используя ваш пример:

awk '{sum+=$1} END {print sum}' file

решение2

Если у вас есть контроль над программой awk, выполните добавление в awk, как показывает @jasonwryan.

Если вы действительно хотите суммировать числа, которые выдает awk, направьте вывод в одну из следующих команд:

| { tr '\n' '+' ; echo 0; } | bc
| { while read line; do ((sum+=line)); done; echo $sum; }

Во втором примере команда echo находится внутри группирующих фигурных скобок, поскольку bash запускает конвейер в подоболочке, поэтому изменения в переменной $sum не будут существовать при выходе из подоболочки.

решение3

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

n=0;while read i; do let n+=$i; done < <(awk '{print $1}' foo); echo $n;

или

n=0;while read i; do n=$((n+i)); done < <(awk '{print $1}' foo); echo $n;

Он n=0нужен только для того, чтобы убедиться, что $nон всегда равен 0, в противном случае при повторном запуске этих команд будет возвращено 252 вместо 126.


Хотя самым простым способом gawkдля выполнения вычислений было бы использовать , вы также можете использовать однострочный код Perl:

awk '{print $1}' foo | perl -lne '$k+=$_;END{print "$k"};'

Флаг -lудаляет новые строки ( chomp) и добавляет один в конец каждой выведенной строки, что -nозначает построчное чтение файла, сохранение каждой строки как $_и запуск предоставленного скрипта -e.

Или сделать все это на Perl:

perl -alne '$k+=$F[0];END{print "$k"};' foo

Флаг -aдля Perl включает автоматическое разделение строк (типа gawk). По умолчанию поля разделяются пробелами, но это можно изменить с помощью -F. Полученные поля сохраняются как @Fмассив, поэтому первое поле — $F[0].

решение4

Однострочный метод, который я обычно использую для простых итогов, таких как этот, заключается в передаче в xargs для получения всех выходных данных из awk в одной строке, затем через sed для преобразования пробелов в плюсы и, наконец, в bc для выполнения вычисления:

cat foo | awk '{print $1} | xargs | sed -e 's/ /+/g' | bc

Связанный контент