在linux命令行上做数学运算

时间:2011-11-30 20:18:17

标签: bash awk

我有一个来自Web服务器的日志文件,如下所示;

1908 462
232 538
232 520
232 517

我的任务是在bash脚本中总计第1列和第2列。我想要的输出是;

2604 2037

我知道awksed可以解决我的问题,但我无法理解如何实际解决问题。我在谷歌上搜索了一些例子,但没有发现任何有用的东西。有人能指出我正确的方向吗?

4 个答案:

答案 0 :(得分:6)

awk '{a += $1; b += $2} END { print a " " b }' foo.log

(注意完全没有错误检查。)

编辑:

好的,这是一个带错误检查的版本:

awk 'BEGIN { ok = 1 } { if (/^ *[0-9]+ +[0-9]+ *$/) { a += $1; b += $2 } else { ok = 0; exit 1 } } END { if (ok) print a, b }' foo.log

如果您不想接受前导空格或尾随空格,请删除if语句中的两个" *"

但这足够大,它可能不应该是一个单行:

#!/usr/bin/awk -f

BEGIN {
    ok = 1
}

{
    if (/^ *[0-9]+ +[0-9]+ *$/) {
        a += $1
        b += $2
    }
    else {
        ok = 0
        exit 1
    }
}

END {
    if (ok) print a, b
}

仍然没有溢出或下溢检查,并且它假定没有任何迹象。后者很容易修复;前者会更难。 (注意awk在内部使用浮点;如果总和足够大,它可能会悄然失去精度。)

答案 1 :(得分:3)

尝试

awk '{a+=$1;b+=$2} END {print a, b}' file

答案 2 :(得分:0)

这是一个非awk替代方案:

echo $( cut -f 1 -d " " log_file | tr '\n' + | xargs -I '{}' echo '{}'0 | bc ) $( cut -f 2 -d " " log_file | tr '\n' + | xargs -I '{}' echo '{}'0 | bc )

确保将log_file替换为您自己的文件,并且该文件没有任何额外或不必要的新行。如果你有这样的行,那么我们需要使用如下命令过滤掉那些:

grep -v "^\s*$" log_file

答案 3 :(得分:0)

这些可能适合您:

sed ':a;N;s/ \(\S*\)\n\(\S*\) /+\2 \1+/;$!ba;s/ /\n/p;d' file | bc | paste -sd' '

echo $(cut -d' ' -f1 file | paste -sd+ | bc) $(cut -d' ' -f2 file| paste -sd+ |bc)