Intereting Posts

Как добавить каждый вывод 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?

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

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

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

Если вы действительно хотите подытожить цифры, которые вырывают awk, проведите вывод в один из них:

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

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

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 поэтому 1-е поле равно $F[0] .

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

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