我有一个日志文件。对于每一行带有特定数字的行,我想计算这些行的最后一个数字之和。使用 grep 和 cut 没问题,但我不知道如何计算数字之和。我尝试了 StackExchange 的一些解决方案,但在我的案例中没有奏效。
这是我到目前为止所拥有的:
grep "30201" logfile.txt | cut -f6 -d "|"
30201 是我正在寻找的线路。
我想将最后的数字 650、1389 和 945 相加
日志文件.txt
Jan 09 2016|09:15:17|30201|1|SL02|650
Jan 09 2016|09:15:18|43097|1|SL01|945
Jan 09 2016|09:15:19|28774|2|SB03|1389
Jan 09 2016|09:16:21|00788|1|SL02|650
Jan 09 2016|09:17:25|03361|3|SL01|945
Jan 09 2016|09:17:33|08385|1|SL02|650
Jan 09 2016|09:18:43|10234|1|SL01|945
Jan 09 2016|09:21:55|00788|1|SL02|650
Jan 09 2016|09:24:43|03361|3|SB03|1389
Jan 09 2016|09:26:01|30201|1|SB03|1389
Jan 09 2016|09:26:21|28774|2|SL02|650
Jan 09 2016|09:26:25|00788|1|SL02|650
Jan 09 2016|09:27:21|28774|2|SL02|650
Jan 09 2016|09:29:32|30201|1|SL01|945
Jan 09 2016|09:30:12|34032|1|SB03|1389
Jan 09 2016|09:30:15|08767|3|SL02|650
答案1
您可以寻求帮助,以适合进行加法的paste
格式序列化数字:bc
% grep "30201" logfile.txt | cut -f6 -d "|"
650
1389
945
% grep "30201" logfile.txt | cut -f6 -d "|" | paste -sd+
650+1389+945
% grep "30201" logfile.txt | cut -f6 -d "|" | paste -sd+ | bc
2984
如果你有grep
PCRE,你可以grep
单独使用积极的后向来做到这一点:
% grep -Po '\|30201\|.*\|\K\d+' logfile.txt | cut -f6 -d "|" | paste -sd+ | bc
2984
单独使用awk
:
% awk -F'|' '$3 == 30201 {sum+=$NF}; END{print sum}' logfile.txt
2984
-F'|'
将字段分隔符设置为|
$3 == 30201 {sum+=$NF}
如果第三个字段是,则将最后一个字段的值相加30201
END{print sum}
打印sum
在END
答案2
您的 grep 和 cut 命令没有任何问题。您可以使用“|30201|”使其更加健壮作为搜索模式。接下来的问题是处理输出。
使用bash:
#!/bin/bash
# get the output as a bash array and add the elements
nums=( $(grep "|30201|" logfile.txt | cut -f6 -d "|") )
total=0
for i in ${!nums[@]}
do
total=$(($total+${nums[i]}))
done
echo $total
答案3
重击解决方案。
#!/bin/bash
pa=0 ; s=0 ;
while read a b ; do \
if [ "$a" == "$pa" ] ; then \
s=$(($s+$b)) ;
else
if [ "$pa" != 0 ] ; then \
echo $pa $s ;
fi ;
pa=$a ; s=$b ;
fi ;
done < <(cat j.txt | awk -F'|' '{printf("%s %s\n",$3,$6)}' | sort -n)
echo $pa $s
初始化前一个 A 和 SUM
减少字段 3 和 6 的输入并按数字排序
只要字段 3 保持不变就循环,将字段 6 添加到 SUM
如果字段 3 发生变化但前一个 A 不为 0,则输出前一个 A 和 SUM,并将前一个 A 重新初始化为 a,将 SUM 重新初始化为最后读取的字段 6。
输出最后一个 Previous A 和 SUM。
给定输入的输出:
00788 1950
03361 2334
08385 650
08767 650
10234 945
28774 2689
30201 2984
34032 1389
43097 945
答案4
我随身携带一个小工具,我称之为 sumcol
#!/bin/sh
# Icarus Sparry. Free for any use.
C=${1:?"missing required column number"}
shift
awk '{s+=$'"$C"'} END { print s }' "$@"
这会将您提供的空白分隔列相加。虽然我会写(就像@heemayl 所做的那样)
awk -F'|' '$3 == 30201 {s+=$6} END{ print s}' logfile.txt
对于OP的问题,他可以使用
grep "30201" logfile.txt | cut -f6 -d "|" | sumcol 1
或者
grep "30201" logfile.txt | tr "| " " _" | sumcol 6