Home  >  Q&A  >  body text

shell - linux:怎样从复杂的log中提取信息

例如在文件1.log中
id=1
a=1,b=2,c=3,d=4,e=5....,z=100

id=2
a=3,b=4,d=20,e=6,f=7,...,z=30

id=3
a=4,b=4,c=2,d=5,e=8,...,z=29

....
现在我想统计在log中d的分布~
有什么好方法吗? grep每次都是输出整行,没法提取一个关键词的信息。

黄舟黄舟2741 days ago686

reply all(7)I'll reply

  • 怪我咯

    怪我咯2017-04-17 11:10:35

    awk的解法:

    #!/bin/bash
                                    
    awk -F"," '
    NF == 0 {next}    # skip blank line
    NF == 1 {printf "%s ", $1}    # for id line
    # for data line
    {
        for (i = 1; i <= NF; i++) {
            split($i, a, "=");
            if (a[1] == "d") print $i;
        }
    }
    ' 1.log

    结果如下:
    id=1 d=4
    id=2 d=20
    id=3 d=5

    awk的好处在于可以对输入/输出的格式作比较精细的处理。

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 11:10:35

    先去掉id=中的d=, 然后
    grep -o 参数 提取匹配的模式。 再把数字再抓出来, awk或者cut就可以了。

    grep -v "id=[0-9]*" 1.log | grep -o "d=[0-9]*" | awk -F'=' '{ print $2 }' 

    或者, 用egrep,

    grep -v "id=[0-9]*" 1.log | egrep -o "d=[0-9]+" | cut -d '=' -f 2

    方法还是多啦, 其他sed那些 都可以用;

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 11:10:35

    给个其他思路...

    mv 1.log /opt/www/1.log

    然后用php脚本来处理,新建一个1.php.脚本如下:

    <?php
    $str = file_get_contents("1.log");  
    $arr = explode(",",$str);
    foreach($arr as $k=>$v){
    	$b = explode("=",$v);
    	if($b[0]=="d"){
    		$new_arr[] = $b[1];
    	}
    }
    print_r($new_arr);
    ?>

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 11:10:35

    这个比较适合用 awk 或者 flex 来做。

    flex:

    $ cat 1.l 
    %%
    d=[0-9]*,   printf("%d\n", atoi(yytext + 2));
    
    .|\n
    
    $ flex 1.l && gcc lex.yy.c -lfl && ./a.out < 1.txt 
    4
    20
    5

    reply
    0
  • 怪我咯

    怪我咯2017-04-17 11:10:35

    这种 log 处理 awk、perl、ruby 都行。上个 perl 版

    perl -ne 'print $1 if m/d=(\d+)/' your_log_file

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 11:10:35

    用Python吧,什么OS下面都很好用。

    import re
    _re.compile('d=\\d+')
    # readline in 'line'
    matched = _re.search(line)
    if matched:
        extracted = matched.group(0)
    print extracted

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 11:10:35

    用cut命令吧。
    cut -d '分割字符' -f '选取第几段的意思'
    好像还有个参数 -c。

    $ cat 1.log |cut -c 0-4 |cut -d ',' -f 4

    可以自己man 一下。

    reply
    0
  • Cancelreply