我有一个来自Web服务器的日志文件,如下所示;
1908 462
232 538
232 520
232 517
我的任务是在bash脚本中总计第1列和第2列。我想要的输出是;
2604 2037
我知道awk
或sed
可以解决我的问题,但我无法理解如何实际解决问题。我在谷歌上搜索了一些例子,但没有发现任何有用的东西。有人能指出我正确的方向吗?
答案 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)