如何添加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 在子 shell 中运行管道,因此当子 shell 退出时,对 $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) 并在每个打印字符串的末尾添加 1,这-n意味着逐行读取文件,将每一行保存为$_并运行 提供的脚本-e

或者用 Perl 完成整个事情:

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

Perl 的标志-a打开自动行分割(如gawk)。默认情况下,字段按空格分割,但可以使用 进行更改-F。结果字段保存为@F数组,因此第一个字段是$F[0]

答案4

我通常用于像这样的简单总计的单行方法是通过管道传输到 xargs 以在一行上获取 awk 的所有输出,然后通过 sed 将空格转换为加号,最后转换为 bc 进行计算:

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

相关内容