【问题标题】:search value and count number from log file从日志文件中搜索值和计数
【发布时间】:2015-08-29 23:46:47
【问题描述】:

我在日志文件中有如下值,我想捕获所有相同的数字并计算它们,然后每 10 分钟放入另一个文件。我们该怎么做呢?

[14/06/2015 14:33:55.311] - 警告 - 在两个来源之间检测到冲突!!! id1=67 id2=69 编号=1193046 [14/06/2015 14:33:55.607] - 警告 - 在两个来源之间检测到冲突!!! id1=70 id2=69 编号=1193046 [14/06/2015 14:33:55.886] - 警告 - 在两个来源之间检测到冲突!!! id1=69 id2=70 数字=466000000 [14/06/2015 14:33:56.086] - 警告 - 在两个来源之间检测到冲突!!! id1=64 id2=69 编号=1193046 [14/06/2015 14:33:57.064] - 警告 - 在两个来源之间检测到冲突!!! id1=70 id2=69 编号=1193046 [14/06/2015 14:33:57.074] - 警告 - 在两个来源之间检测到冲突!!! id1=64 id2=69 编号=1193046 [14/06/2015 14:33:57.454] - 警告 - 在两个来源之间检测到冲突!!! id1=68 id2=70 数字=466000000 [14/06/2015 14:33:57.657] - 警告 - 在两个来源之间检测到冲突!!! id1=68 id2=70 数字=466000000 [14/06/2015 14:33:57.657] - 警告 - 在两个来源之间检测到冲突!!! id1=68 id2=70 数字=466000000 [14/06/2015 14:33:58.309] - 警告 - 在两个来源之间检测到冲突!!! id1=67 id2=70 数量=466000000 [14/06/2015 14:33:58.610] - 警告 - 在两个来源之间检测到冲突!!! id1=70 id2=69 编号=1193046 [14/06/2015 14:33:58.814] - 警告 - 在两个来源之间检测到冲突!!! id1=68 id2=69 编号=1193046 [14/06/2015 14:33:58.874] - 警告 - 在两个来源之间检测到冲突!!! id1=69 id2=70 数字=466000000

【问题讨论】:

  • 另一方面,如果记录此数据的代码 - 如果您拥有该代码,请尝试以 YYYY/MM/DD HH:mm:SS.ms 格式打印时间戳(时间单位的递减顺序)。这对于排序和简单的字符串比较变得容易。目前,如果您只想选择最近 10 分钟的数据,则必须进行一些复杂的字符串操作和算术运算。

标签: linux bash perl shell unix


【解决方案1】:

假设Data::Dump 的输出格式足够好,这对于 Perl 来说是一个小问题

perl -MData::Dump -e"/number=(\d+)/ and ++$c{$1} while <>; dd \%c;"  logfile.log

输出

{ 1193046 => 7, 466000000 => 6 }

如果(无论出于何种原因)您无法安装 Data::Dump,那么核心模块 Data::Dumper 的输出会稍微不那么整洁

perl -MData::Dumper -e"/number=(\d+)/ and ++$c{$1} while <>; print Dumper \%c;"  logfile.log

输出

$VAR1 = {
          '1193046' => 7,
          '466000000' => 6
        };

【讨论】:

    【解决方案2】:

    在 while 循环中使用单行代码:

    while true; do 
        awk '{a[$NF]++}END{for(t in a){printf "%d\t%s\n", a[t], gensub(/number=/,"",1,t)}}' logfile
        sleep 600
    done
    

    输出:

    6       466000000
    7       1193046
    

    【讨论】:

    • 我通常不会回答这个问题,因为 OP 没有显示任何解决问题的努力。回答是因为接受的答案(某种)表明方法效率低下。在 OP 发布他尝试过的一些代码后,我将在答案中添加解释。
    • 我尝试了 enrico 的建议并找到了我预期的输出,这就是我接受答案的原因。
    【解决方案3】:

    此 perl 脚本将打印出您的号码并每隔 10 分钟在一个新文件 ('outfile.file number.txt') 中计算该号码

    use warnings;
    use strict; 
    
    my %hash;
    my $count;
    while (1) {
        open my $in, '<', 'in.txt' or die $!;
        $count++;
            while(<$in>){
                chomp;
                my ($number) = /number=(\d+)/;
                $hash{$number}++;
            }
        open my $out, '>', "outfile.$count.txt" or die $!;
        print $out "$_\t$hash{$_}\n" foreach keys %hash;
        sleep 600;
    }
    

    【讨论】:

      【解决方案4】:

      我会这样做:

      cat log | grep -o "number\=[0-9]\+" | cut -d= -f2 | sort | uniq -c
      

      您的示例的输出是:

      7 1193046
      6 466000000
      

      【讨论】:

      • 太好了,如何每 10 分钟收集一次,因为我只想收集最近 10 分钟在日志文件中新登录的号码。
      • 整个管道可以简化为一个awk
      • @anishsane:当然可以,但通常也更难阅读。
      • 1. ^^ 我不同意这个。对于新人,您需要了解所有命令的不同选项的含义。 2. 另外,通常避免使用sort | uniq -c,因为当您只需要计数时,这会不必要地消耗更多内存。今天,内存在桌面系统上可能不再是一个限制因素,但 linux 也确实在嵌入式系统上得到了使用。因此,拥有一个统一的脚本通常是一个好主意。 3.cat | grepuuoc。与grep | cutsort | uniq -c 类似的情况。建议减少进程数量...
      • & 我并不是说你的答案是错误的。只是效率低下。顺便说一句,我没有拒绝你的回答;除非答案是“错误的”,否则我不会对答案投反对票... :-)
      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 2011-09-18
      • 2021-07-23
      • 2011-05-01
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      相关资源
      最近更新 更多