zoukankan      html  css  js  c++  java
  • awk命令分析日志的简单笔记

    awk是一个文本分析工具,可以用来进行流量日志分析

    之前无意中看到了这个命令,简单记一下笔记 ,在打线下的时候可能会有用

    awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk。

    有三种方式调用awk

    复制代码
    1.命令行方式
    awk [options]  'script'  filename
    其中,script 是真正awk命令,[-F域分隔符]是可选的。filename 是待处理的文件。
    在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。
    2.shell脚本方式
    将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。
    相当于shell脚本首行的:#!/bin/sh
    可以换成:#!/bin/awk
    
    3.将所有的awk命令插入一个单独文件,然后调用:
    awk -f scriptfile   filename
    其中,-f选项加载awk-script-file中的awk脚本
    复制代码

    options 是命令选项 -- 比如几个常用命令选项

      -F xx  以xx为分隔符,awk的默认分隔符为空格   例如 -F ':' 这样

      -f scriptfile  从脚本文件中读取awk命令  这时候就不需要后面的'script'了 

      -v var=value   赋值一个用户定义变量,将外部变量传递给awk

    script  则是如何对文本进行处理,支持正则表达式/xxx/,关系表达式即字符串或数字的比较测试,模式匹配表达式--用运算符~(匹配)和~!(不匹配)

      以及     BEGIN{ commands } pattern{ commands } END{ commands } 这三种语句块

      BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中。

      END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块。

      pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块。

    filenames则是要处理的文件名,可以用 |  将之前命令的输出直接用awk处理,就不需要filenames了,也可以将wak的输出通过 |  让head和tail命令来处理

    内置变量

    说明:[A][N][P][G]表示第一个支持变量的工具,[A]=awk、[N]=nawk、[P]=POSIXawk、[G]=gawk

    复制代码
    $n 当前记录的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段。  
    $0 这个变量包含执行过程中当前行的文本内容。  
    [N] ARGC 命令行参数的数目。  
    [G] ARGIND 命令行中当前文件的位置(从0开始算)。  
    [N] ARGV 包含命令行参数的数组。  
    [G] CONVFMT 数字转换格式(默认值为%.6g)。  
    [P] ENVIRON 环境变量关联数组。  
    [N] ERRNO 最后一个系统错误的描述。  
    [G] FIELDWIDTHS 字段宽度列表(用空格键分隔)。  
    [A] FILENAME 当前输入文件的名。  
    [P] FNR 同NR,但相对于当前文件。  
    [A] FS 字段分隔符(默认是任何空格)。  
    [G] IGNORECASE 如果为真,则进行忽略大小写的匹配。  
    [A] NF 表示字段数,在执行过程中对应于当前的字段数。  
    [A] NR 表示记录数,在执行过程中对应于当前的行号。  
    [A] OFMT 数字的输出格式(默认值是%.6g)。  
    [A] OFS 输出字段分隔符(默认值是一个空格)。  
    [A] ORS 输出记录分隔符(默认值是一个换行符)。  
    [A] RS 记录分隔符(默认是一个换行符)。  
    [N] RSTART 由match函数所匹配的字符串的第一个位置。  
    [N] RLENGTH 由match函数所匹配的字符串的长度。  
    [N] SUBSEP 数组下标分隔符(默认值是34)。
    复制代码

    输出函数

    awk中同时提供了print和printf两种打印输出的函数。

    其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。

    printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂

    简单函数用法

    打开外部文件 close函数

    awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}'  

    逐行读取外部文件内容 getline

    awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}'  

    调用外部应用程序 system函数

    awk 'BEGIN{b=system("ls -al");print b;}'

    字符串操作

    查找字符串  index函数

    awk 'BEGIN{info="this is a test2010test!";print index(info,"test")?"ok":"no found";}'  

    正则表达式查找匹配

    awk 'BEGIN{info="this is a test2010test!";print match(info,/[0-9]+/)?"ok":"no found";}'  

    字符串截取

    awk 'BEGIN{info="this is a test2010test!";print substr(info,4,10);}'  

    字符串分割

    awk 'BEGIN{info="this is a test";split(info,tA," ");print length(tA);for(k in tA){print k,tA[k];}}'  

    去实验吧随便找了个日志的题目 然后拿日志过来试一试

    不知道为什么突然上传不了图片了只有贴一下数据 简单测试一下

    复制代码
    root@ubuntu:~# cat log | head -10
    192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET / HTTP/1.1" 302 -
    192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/ HTTP/1.1" 302 -
    192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/splash.php HTTP/1.1" 200 1321
    192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/xampp.css HTTP/1.1" 200 3991
    192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/img/blank.gif HTTP/1.1" 200 43
    192.168.1.2 - - [16/Dec/2010:01:21:10 +0800] "GET /xampp/img/xampp-logo.jpg HTTP/1.1" 200 19738
    192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/lang.php?zh HTTP/1.1" 302 -
    192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/index.php HTTP/1.1" 200 589
    192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/head.php HTTP/1.1" 200 1362
    192.168.1.2 - - [16/Dec/2010:01:21:44 +0800] "GET /xampp/start.php HTTP/1.1" 200 534
    复制代码

     用 / 分割 输出第一部分

    复制代码
    root@ubuntu:~# awk -F '/'  '{print $1}' log | head -10
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    192.168.1.2 - - [16
    复制代码

    用-分割 输出第一部分和最后一部分

    复制代码
    root@ubuntu:~# awk -F '-'  '{print $1,$NF}' log | head -10
    192.168.1.2  
    192.168.1.2  
    192.168.1.2   [16/Dec/2010:01:21:10 +0800] "GET /xampp/splash.php HTTP/1.1" 200 1321
    192.168.1.2   [16/Dec/2010:01:21:10 +0800] "GET /xampp/xampp.css HTTP/1.1" 200 3991
    192.168.1.2   [16/Dec/2010:01:21:10 +0800] "GET /xampp/img/blank.gif HTTP/1.1" 200 43
    192.168.1.2  logo.jpg HTTP/1.1" 200 19738
    192.168.1.2  
    192.168.1.2   [16/Dec/2010:01:21:44 +0800] "GET /xampp/index.php HTTP/1.1" 200 589
    192.168.1.2   [16/Dec/2010:01:21:44 +0800] "GET /xampp/head.php HTTP/1.1" 200 1362
    192.168.1.2   [16/Dec/2010:01:21:44 +0800] "GET /xampp/start.php HTTP/1.1" 200 534
    复制代码

    统计总行数

    root@ubuntu:~# awk  'BEGIN{x=0;} {x++;} END{print x}' log 
    929
    root@ubuntu:~# wc -l log
    929 log

    用/分割  把输出的最后两个部分写进looog文件中

    复制代码
    root@ubuntu:~# awk -F '/'  '{print $(NF-1),$NF}' log > looog
    awk: cmd. line:1: (FILENAME=log FNR=929) fatal: attempt to access field -1

    root@ubuntu:~# cat looog | tail -10 pixel.gif HTTP 1.1" 404 1337 admin HTTP 1.1" 403 1110 login.php HTTP 1.1" 403 1110 robots.txt HTTP 1.1" 200 264 admin.php HTTP 1.1" 200 3763 pixel.gif HTTP 1.1" 404 1279 pixel.gif HTTP 1.1" 404 1279 admin.php HTTP 1.1" 200 3762 pixel.gif HTTP 1.1" 404 1279 pixel.gif HTTP 1.1" 404 1279
    复制代码

    查找最后20行内有没有 'php'   不用三元表达式就会直接返回位置

    复制代码
    root@ubuntu:~# awk '{print index($0,"php")?"find":"no"}' log | tail -20
    no
    no
    no
    no
    no
    find
    find
    find
    no
    no
    no
    find
    no
    find
    no
    no
    find
    no
    no
    no
    复制代码

    用正则查找

    复制代码
    root@ubuntu:~# awk '{print match($0,"php")?"find":"no"}' log | tail -20
    no
    no
    no
    no
    no
    find
    find
    find
    no
    no
    no
    find
    no
    find
    no
    no
    find
    no
    no
    no
    复制代码

    截取前五个字符

    复制代码
    root@ubuntu:~# awk '{print substr($0,5,5)}' log | tail -10
    168.1
    168.1
    168.1
    168.1
    168.1
    168.1
    168.1
    168.1
    168.1
    复制代码

    参考资料

    https://blog.csdn.net/u011204847/article/details/51205031

    https://www.cnblogs.com/lyftest/p/7373453.html

    http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

  • 相关阅读:
    Swift_Set详解
    Swift_数组详解
    Swift_字符串详解(String)
    选择排序_C语言_数组
    插入排序_C语言_数组
    快速排序_C语言_数组
    冒泡排序_C语言_数组
    七牛直播收获分享
    iOS 实用博客整理(连载版)
    iOS Swift-元组tuples(The Swift Programming Language)
  • 原文地址:https://www.cnblogs.com/rxbook/p/10463477.html
Copyright © 2011-2022 走看看