Как бы вы выполнили сложение выводимых данных каждой строки из 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