如何从文件中 grep 和剪切数字并对它们求和

如何从文件中 grep 和剪切数字并对它们求和

我有一个日志文件。对于每一行带有特定数字的行,我想计算这些行的最后一个数字之和。使用 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

如果你有grepPCRE,你可以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}打印sumEND

答案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

相关内容