zoukankan      html  css  js  c++  java
  • 日志处理中一些shell命令技巧

    日志处理中一些shell命令技巧

    阴差阳错的做的日志分析,前途未卜的这段日子,唯一还有点意思的可能就是手动的处理大量日志。总结一下。

    日志文件的输入是动则几个G的文本。从N个这样的文件中得到一个列表,一个数字,一个比例。在什么工具都没有情况下,用shell命令不仅是验证系统数据的准确性的方法,也是一个很好的学习过程。

    使用cut命令切割日志行

    下面的一行典型的apache访问日志:

    120.51.133.125 - - [26/Apr/2013:12:20:06 +0800] "GET /skins/skin_homepage.php?display=wvga&lang=ja_JP&pixel=720X1280&density=2.0&version=5.7&key=5146f54950f09f71750005ef&uid=1 HTTP/1.1" 200 4847 "http://t.co/rww3WDuhS5" "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; YTB730)" 0 

    如果需要得到IP地址可以使用cut命令

     cat log | cut -d ' ' -f1 

    -d ' '表示按照空格将行切开,-f1 取第一个字段,这样得到的结果就是IP列表

    有时候拿到的文件是 分隔,也可以使用cut切开,只不过需要多写一个$

    [l]$ cat log | cut -d '	' -f1 cut: the delimiter must be a single character #-d '	'会报错的 cut -f2 -d$'	' infile #work 

    使用tr命令去掉字符,替换字符

    -c:complement,用SET2替换SET1中没有包含的字符
    -d:delete,删除SET1中所有的字符,不转换
    -s: squeeze-repeats,压缩SET1中重复的字符
    -t: truncate-set1,将SET1用SET2转换,一般缺省为-t

    如果拿到分割的文件

    cat log | tr -s ' ' ',' 

    zzx@zzx103:~/dhcptest$ echo "aaacccddd ss " | tr -s [a-c]   # -s
    acddd ss

    zzx@zzx103:~/dhcptest$ echo "aaacccddd  ss " | tr -s " " ","  #d和s之间有2个空格,替换后压缩重复
    aaacccddd,ss,

    zzx@zzx103:~/dhcptest$ echo "aaacccddd  ss " | tr -t " " ","
    aaacccddd,,ss,

    zzx@zzx103:~/dhcptest$ echo "aaacccddd  ss " | tr -s "a" "b" #替换后压缩重复
    bcccddd ss

    将空格替换成,文件变成csv

    cat log | tr -d ' ' 

    上面的命令直接删除空格   

    日志处理后经常会出现空行,tr命令去掉空行的原理就是将连续两个换行替换成一个换行

    cat log | tr -s '
    
    ' '
    ' 

    使用uniq命令去重

    试想得到IP列表,欲得到独立访问的IP列表。

    [l]$ cat log | cut -d ' ' -f1 | uniq -u 

    如果不仅仅是去重,还想统计每个IP访问次数,可以加一个参数c

    [l]$ cat log | cut -d ' ' -f1 | uniq -uc 

    得到的格式形如:

    1 126.193.38.128 5 49.98.156.154 

    前面的数字就是出现的次数

    使用awk/seed来处理日志

    awk/seed是处理日志的最终的万金油。确实是什么都可以做。awk/seed是一门很大的学问。这里取我碰到的一个日志,日志格式形如:

    display=wvga|||lang=ja_JP|||isActive=1|||pixel=720X1280|||density=2.0|||version=5.7|||key=5146f54950f09f71750005ef|||out=abc'3|||uid=1 

    如果我需要得到isActive=1的日志行,取到out=中'前一段,如上面的abc。

    cat l | grep "isActive=1|" | awk 'match($0,/out=[^x27]+/){print substr($0,RSTART+4,RLENGTH-4)}' 

    grep的功能是筛选isActive=1的行。awk 后面跟''的是awk语言。$0总是代表当前匹配的字段值,match substr是awk可以用的函数,当match时后面{}中的代码才会执行。当match,$0就是正则匹配的部分。RSTART,RLENGTH是awk可以使用的常量,分别表示开始匹配的开始下标,RLENGTH是匹配的长度。

    在''中需要再使用'光转义是不行的,得用16进制的代码x27。转16进制可以使用python代码 "'".encode("hex")得到

    //惊讶awk就这么简单的解释了,可这连入门都算不上。

    集合操作

    试想我想得到两个列表的交际,并集,差集,统计中经常会碰到,比如我想获得昨天今天都在访问的IP,其实就是今天的IP列表和昨天IP列表的交集。

    先定义两个简单的文件:

    [ l]$ cat a.txt 1 2 3 4 5 [ l]$ cat b.txt 4 5 6 7 8 9 

    如果想得到ab的交集4 5 ,可以使用下面的命令:

    sort -m a.txt b.txt | uniq -d 4 5 

    如果要得到并集1-9,可以:

    sort -m a.txt b.txt | uniq 1 2 3 4 5 6 7 8 9 

    如果想得到ab的差集,即a去掉ab的交集1 2 3

    comm -23 a.txt b.txt 1 2 3 

    同理:ba的差集:

    comm -13 a.txt b.txt comm -23 b.txt a.txt 

    上述两个命令等价

    comm命令就是compare功能,如果什么参数都不带呢得到的什么呢?

    comm a.txt b.txt 1 2 3 4 5 6 7 8 9 

    diff命令以前经常看代码改了哪些:

    diff a.txt b.txt  1,3d0 < 1 < 2 < 3 5a3,6 > 6 > 7 > 8 > 9 

    总结&&参考资料

    窃以为能玩转上面这些命令,处理个日志问题不大了。

    一篇介绍shell中集合操作的博文:

    http://wordaligned.org/articles/shell-script-sets

    一直放在收藏夹的shell方面的博客:

    Linux Shell常用技巧

    Linux Shell高级技巧 awk部分写的独好

  • 相关阅读:
    centos7下配置时间同步服务器
    交换机简单配置(转)
    ubuntu16.04安装docker CE
    docker下使用DB2
    iptables之centos6版本详解
    iptables之centos6版本常用设置
    iptables介绍iptables和netfilter
    git的使用学习(九)搭建git服务器
    js 图片预览
    ps -ef | grep java 查看所有关于java的进程
  • 原文地址:https://www.cnblogs.com/hanxing/p/4113554.html
Copyright © 2011-2022 走看看