如何对 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