• 一天一个 Linux 命令(21):awk 命令


    一天一个 Linux 命令(21):awk 命令

    一、简介

    awk是一个强大的文本分析工具,简单来说awk就是把文件逐行读入,(空格,制表符)为默认分隔符将每行切片,切开的部分再进行各种分析处理;

    awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确拥有自己的语言: AWK 程序设计语言 , 三位创建者已将它正式定义为“样式扫描和处理语言”。它允许创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。

    相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

    二、格式说明

    awk [POSIX or GNU style options] -f progfile [--] file ...
    awk [POSIX or GNU style options] [--] 'program' file ...
    awk '{pattern + action}' {file}
    awk [选项参数] 'script' var=value file(s)
    awk [选项参数] -f scriptfile var=value file(s)
    
    Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
    Usage: awk [POSIX or GNU style options] [--] 'program' file ...
    POSIX options:          GNU long options: (standard)
            -f progfile             --file=progfile
            -F fs                   --field-separator=fs
            -v var=val              --assign=var=val
    Short options:          GNU long options: (extensions)
            -b                      --characters-as-bytes
            -c                      --traditional
            -C                      --copyright
            -d[file]                --dump-variables[=file]
            -e 'program-text'       --source='program-text'
            -E file                 --exec=file
            -g                      --gen-pot
            -h                      --help
            -L [fatal]              --lint[=fatal]
            -n                      --non-decimal-data
            -N                      --use-lc-numeric
            -O                      --optimize
            -p[file]                --profile[=file]
            -P                      --posix
            -r                      --re-interval
            -S                      --sandbox
            -t                      --lint-old
            -V                      --version
    
    To report bugs, see node `Bugs' in `gawk.info', which is
    section `Reporting Problems and Bugs' in the printed version.
    
    gawk is a pattern scanning and processing language.
    By default it reads standard input and writes standard output.
    
    Examples:
            gawk '{ sum += $1 }; END { print sum }' file
            gawk -F: '{ print $1 }' /etc/passwd
    

    awk语言的最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。完整的awk脚本通常用来格式化文本文件中的信息。

    通常,awk是以文件的一行为处理单位的。awk每接收文件的一行,然后执行相应的命令,来处理文本。

    三、选项说明

    -f progfile,--file=progfile 从文件progfile中读取AWK程序源代码,而不是从第一个命令行参数中读取。
    可以使用多个-f(或——file)选项。
    
    -F fs,--field-separator=fs  使用fs作为输入字段分隔符(fs预定义变量的值)。
    
    -v var=val,--assign=var=val 在程序开始执行之前,给变量var赋值val。这样的变量值是AWK程序的BEGIN块可用。
    -b,--characters-as-bytes 将所有输入数据视为单字节字符。换句话说,当试图将字符串处理为多字节字符时,不要注意任何语言环境信息。
    
    -c,--traditional 在兼容性模式下运行。在兼容模式下,gawk的行为与UNIX awk相同;没有一个GNU可以识别特定的扩展。
    -C,--copyright 在标准输出上打印GNU版权信息的简短版本并成功退出。
    
    -d[file,--dump-variables[=file] 打印一个排序的全局变量列表,它们的类型和最终值到文件
    
    -e 'program-text',--source='program-text' 使用程序文本作为AWK程序源代码
    
    -E file,--exec=file,与-f类似,这个选项是最后处理的选项
    
    -g,--gen-pot 扫描并解析AWK程序,并在标准输出上生成一个GNU .pot(可移植对象模板)格式文件,其中包含程序中所有可本地化字符串的条目
    
    -h,--help
    
    -L [fatal],--lint[=fatal] 对可疑的或不可移植到其他AWK实现的构造提供警告
    
    -n,--non-decimal-data 识别输入数据中的八进制和十六进制值
    
    -N,--use-lc-numeric 迫使gawk在解析输入数据时使用语言环境的小数点字符
    
    -O,--optimize 启用优化程序的内部表示 
    -p[file],--profile[=file] 发送分析数据到profile
    -P,--posix 打开兼容性模式
    -r,--re-interval 在正则表达式匹配中启用间隔表达式
    -S,--sandbox 在沙箱模式下运行gawk
    -t,--lint-old 提供关于不能移植到Unix awk原始版本的构造的警告
    -V,--version 在标准输出上打印gawk的这个特定副本的版本信息
    

    四、命令功能

    一次读取一行文本,按输入分隔符进行切片,切成多个组成部分,将每片直接保存在内建的变量中,$1,$2,$3....,引用指定的变量,可以显示指定断,或者多个断。如果需要显示全部的,需要使用$0来引用。可以对单个片断进行判断,也可以对所有断进行循环判断。其默认分隔符为空格

    五、调用awk的三种方式

    5.1 命令行方式

    awk [-F field-separator] 'commands' input-file(s)
    

    其中,commands 是真正awk命令,[-F域分隔符]是可选的。 input-file(s) 是待处理的文件。

    在awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常,在不指名-F域分隔符的情况下,默认的域分隔符是空格。

    5.2 shell脚本方式

    将所有的awk命令插入一个文件,并使awk程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用。

    相当于shell脚本首行的:#!/bin/sh

    可以换成:#!/bin/awk

    5.3 将所有的awk命令插入一个单独文件,然后调用

    awk -f awk-script-file input-file(s)
    

    其中,-f选项加载awk-script-file中的awk脚本,input-file(s)跟上面的是一样的。

    六、awk操作符

    6.1 算术操作符

    -x : 负值
    +x : 转换为数值
    x^y :
    x**y : 次方
    x*y : 乘法
    x/y : 除法
    x+y : 加法 
    x-y : 减法
    x%y : 取模
    

    6.2 字符串操作符

    只有一个,而且不用写出来,用于实现字符串连接

    6.3 赋值操作符

    =
    +=
    -=
    *=
    /=
    %=
    ^=
    **=
    ++
    --
    

    需要注意的是,如果某模式为=号,此时使用/=/可能会有语法错误,就以/[=]/替代

    6.4 布尔值

    awk中,任何非0值或非空字符串都为真,反之为假

    6.5 比较操作符

    x<y
    x<=y
    x>y
    x>=y
    x==y
    x!=y
    x~y
    x!~y
    

    6.6 逻辑操作符

    &&
    ||
    !
    

    6.7 函数调用

    func_name(argu1,argu2,....)
    

    6.8 条件表达式

    selector?if-true-expression:if-false-expression
    
    #example:
    awk -F: '{$3>=1000?usertype="Common user":usertype="Sysadmin or sysUser";printf "%15s:%-s
    ",$1,usertype}' /etc/passwd
    

    七、变量

    7.1 内置变量

    变量描述
    $n 当前记录的第n个字段,字段间由FS分隔
    $0 完整的输入记录
    ARGC 命令行参数的数目
    ARGIND 命令行中当前文件的位置(从0开始算)
    ARGV 包含命令行参数的数组
    CONVFMT 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
    ERRNO 最后一个系统错误的描述
    FIELDWIDTHS 字段宽度列表(用空格键分隔)
    FILENAME 当前文件名
    FNR 各文件分别计数的行号
    FS 字段分隔符(默认是任何空格)
    IGNORECASE 如果为真,则进行忽略大小写的匹配
    NF 一条记录的字段的数目
    NR 已经读出的记录数,就是行号,从1开始
    OFMT 数字的输出格式(默认值是%.6g)
    OFS 输出字段分隔符,默认值与输入字段分隔符一致。
    ORS 输出记录分隔符(默认值是一个换行符)
    RLENGTH 由match函数所匹配的字符串的长度
    RS 记录分隔符(默认是一个换行符)
    RSTART 由match函数所匹配的字符串的第一个位置
    SUBSEP 数组下标分隔符(默认值是/034)
    FS: input field seperator,输入的分隔符,默认为空格
    
    OFS: output field seperator,输出的分隔符,默认为空格
    
    RS: input record seperator,输入的换行符
    
    ORS: output record seperator,输出时的换行符
    
    NF: number of field ,字段个数
    
    #example:
    awk '{print NF}' /etc/passwd :打印每行的最后一个字段为第几个字段,这里是数量引用,不是对应的值引用
    awk '{print $NF}' /etc/passwd : 打印每行中的最后一个字段
    
    NR: number of record,文件中的行数
    
    #example:
    awk '{print NR}' /etc/passwd: 打印行号,其会个行号都显示
    awk 'END{print NR}' /etc/passwd: 显示文本的总行数,其只是在文本处理完成后,只显示一次行号
    awk '{print NR}' file1 file2 : 会每把所有文档进行总的编号,而不是单独对文件进行编号
    
    FNR: 对每个文件进行行数单独编号
    
    #example:
    awk '{print FNR}' file1 file2 : 会对每个文件的行数进行单独的编号显示
    
    FILENAME : awk命令所处理的文件的名称
    
    #example:
    awk '{print FILENAME}' file1 : 显示当前文件名,但会每行显示一次
    awk 'END{print FILENAME}' file1 : 显示当前文件名,但只会显示一次
    
    ARGC: 命令行中参数的个数,其awk命令也算一个参数
    
    #example:
    awk 'END{print ARGC}' /etc/passwd : 显示共有几个参数
    
    ARGV : 其是一个数组,保存的是命令行所给定的各参数
    
    #example:
    awk 'END{print ARGV[0]}' /etc/passwd : 显示第一个参数,默认第一个参数个awk命令本身
    

    7.2 自定义变量

    -v var=VALUE : 在选项位置定义
    
    #example:
    #变量在program中定义时,需要使用引号引起来
    awk 'BEGIN{test="hello";print test}' : 在program中定义
    

    八、print和printf

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

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

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

    8.1 区别

    print
    1、各项目之间使用逗号隔开,而输出时则以空白字符分隔
    2、输出的item可以为字符串或数值,当前记录的字段(如$1)、变量或awk的表达式,数值会先转换为字符串,而后再输出
    3、print命令后面的item可以省略,此时其功能相当于print $0,因此,如果想输出空白行,则需要使用print""
    4、如果引用变量$1或其他的,是不能使用引号引起来
    
    printf
    1、其与print命令最大不同是,printf需要指定format
    2、printf后面的字串定义内容需要使用双引号引起来
    3、字串定义后的内容需要使用","分隔,后面直接跟item1,item2....
    4、format用于指定后面的每个item的输出格式
    5、printf语句不会自动打印换行符,
    
    

    8.2 格式符

    %c: 显示字符的ASCII码
    %d,%i : 显示十进制整数
    %e,%E: 科学计数法数值显示
    %f : 显示为浮点数
    %g,%G: 以科学数法或浮点形式显示数值
    %s: 显示字符串
    %u: 无符号整数
    %%: 显示%号自身,相当于转义
    

    8.3 修饰符

    N: 显示宽度
    -: 左对齐(默认为右对齐)
    +: 显示数值符号
    
    #example:
    awk -F: '{printf "%s
    ",$1}' /etc/passwd
    awk -F: '{printf "username: %s,UID:%d
    ",$1,$3}' /etc/passwd
    awk -F: '{printf "username: %-20s shell: %s
    ",$1,$NF}' /etc/passwd
    

    8.4 输出重定向

    print items > "output-file"
    
    print items >> "output-file"
    
    print items | command
    
    特殊文件描述符:
    /dev/stdin :标准输入
    /dev/stdout:标准输出
    /dev/stderr:错误输出
    /dev/fd/N : 某特定文件描述符,如/dev/stdin就相当于/dev/fd/0
    
    #example:
    awk -F: '{printf "%-15s %i
    ",$1,$3 > "/dev/stderr"}' /etc/passwd
    

    九、PATTERN的使用

    awk [option] 'PATTERN{action}' file1,file2....
    
    1.REGEXP:正则表达式,格式为/regular expression/,仅处理能够被此处模式匹配到的行
    
    #example:
    awk '/^root/{print $1}' /etc/passwd
    awk '!/^root/{print $1}' /etc/passwd
    
    
    relational expression:表达式,其值非0或为非空字符时满足条件,用运算符~(匹配)和!~(不匹配)
    
    $1 ~ /foo/ 或者 $1 == "magedu"
    
    
    2.Ranges : 指定匹配范围,格式为/pat1/,/pat2/
    
    #example:
    awk -F: '(NR>=2&&NR<=10) {print $1}' /etc/passwd
    awk -F: '/^root/,/^myuser/{print $1}' /etc/passwd
    注意:不支持直接给出数字的格式
    
    3.EGIN/END模式 : 特殊模式,仅在awk命令执行前运行一次或结束前运行一次
    
    #example:
    
    #先打印一个表头
    awk -F: 'BEGIN{print "Username    ID    Shell"}{printf "%-10s%-10s%-20s
    ",$1,$3,$7}' /etc/passwd
    
    #打印一个表尾
    awk -F: 'BEGIN{print "username   ID     Shell"}{printf "%-10s%-10s%-20s
    ",$1,$3,$7}END{print "end of report."}' /etc/passwd
    
    4.Empty(空模式):匹配任意输入行
    /正则表达式/:使用通配符的扩展集。
    关系表达式:可以用下面运算符表中的关系运算符进行操作,可以是字符串或数字的比较,如$2>$1选择第二个字段比第一个字段长的行。
    模式匹配表达式:
    模式,模式:指定一个行的范围。该语法不能包括BEGIN和END模式。
    BEGIN:让用户指定在第一条输入记录被处理之前所发生的动作,通常可在这里设置全局变量。
    END:让用户在最后一条输入记录被读取之后发生的动作。
    

    十、控制语句

    10.1 if-else

    if (condition){then-body} else{[else-body]}
    
    #example:
    awk -F: '{if($3>=1000)print $1,$3,$7}' /etc/passwd
    
    awk -F: '{if($3>=1000){printf "Common user: %s
    ",$1} else {printf "root or sysuser: %s
    ",$1}}' /etc/passwd
    
    awk -F: '{if($NF=="/bin/bash")print $1}' /etc/passwd
    
    awk -F: '{if(NF>=7) print $0}' /etc/passwd
    
    #有问题
    df -h | awk -F[%] '/^/dev/{print $1}' | awk {if($NF>=20) print $1}'
    
    awk -F: '{if($1=="root") print $1,"Admin";else print $1, "Common User"}' /etc/passwd
    
    awk -F: '{if($1=="root") printf "%-15s: %s
    ",$1,"Admin";else printf "%-15s: %s
    ",$1, "Common user"}' /etc/passwd
    
    #统计用户ID大于500的有多少行
    awk -F: -v sum=0 '{if($3>=500) sum++}END{print sum}' /etc/passwd
    #可以使用	制表符控制 输出格式
    awk -F: -v OFS="	" '{if($3<=999)printf "Sys user:	%-15s ID is :%d
    ", $1,$3;else{printf "Common user:	%-15s ID is :%d
    ",$1,$3}}' /etc/passwd
    

    10.2 while:用于循环

    while (condition){statement1;statment2;....}
    
    #example:
    awk '/^[[:space:]]*linux16/{print}' /boot/grub2/grub.cfg
    
    #对每个字段进行字符个数统计
    awk '/^[[:space:]]*linux16/{i=1;while(i<=NF){print $i,length($i);i++}}' /etc/grub2.cfg
    awk '/^[[:space:]]]*linux16/{i=1;while(i<=NF){if(length($i)<=7)print $i,length($i);i++}}' /etc/grub2.cfg
    
    #打印用户名、密码占位符、ID
    awk -F: '{i=1;while(i<=3){print $i;i++}}' /etc/passwd
    
    #字段大小大于等于4的都显示
    awk -F: '{i=1;while(i<=NF){if(length($i)>=4){print $i};i++}}' /etc/passwd
    

    10.3 do-while

    do {statement1,statement2,....} while (dondition)
    
    #example:
    #打印用户名、密码占位符、UID
    awk -F: '{i=1;do{print $i;i++}while(i<=3)}' /etc/passwd
    

    10.4 for

    for(variable assignment;condition;iteration process){ statement1,statement2,...}
    
    #example:
    awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++) {print $i,length($i)}}' /etc/grub2.cfg
    awk -F: '{for(i=1;i<=3;i++)print $i}' /etc/passwd
    awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd
    

    10.5 for循环还可以用来遍历数组元素

    for (i in array) {statement1,statement2,....}
    
    #example:
    awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i
    ",A,BASH[A]}}' /etc/passwd
    
    awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
    
    #统计/etc/fstab中各文件系统的次数
    awk '/^UUID/{filesystem[$3]++}END{for (i in filesystem) {print i,filesystem[i]}}' /etc/fstab
    
    #统计各连接状态的次数
    netstat -ant | awk '/^tcp/{state[$NF]++}END{for(i in state) {print i,state[i]}}'
    
    #统计访问日志中各IP的访问次数
    awk '{ip[$1]++} END {for (i in ip) {print i,ip[i]}}' /data/log/nginx/access.log
    

    10.6 case

    switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...}
    

    10.7 break和continue

    break [n]
    continue : 进入下一个字段
    

    10.8 next

    #功能:提前结束本行文本的处理,并接着处理下一行
    
    #example:
    awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
    awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd
    

    十一、awk的数组

    11.1 定义数组

    1、可使用任意字符串,字符串要使用双引号
    2、如果某数组元素事先不存在,在引用时awk会自动创建此元素,并将其初始化为空串
    3、要遍历数组中的每个元素,要使用for循环
    for(var in array){statement1,.....}
    #  注意:var用于引用数组时,是引用的下标,而不是元素值
    

    11.2 定义数组的格式

    awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
    
    统计netstat -ant中各状态的次数
    
    #每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引
    netstat - | awk '/^tcp/{state[$NF]++}END{for(i in state) {print i,state[i]}}'
    
    #统计www服务的访问日志中IP数量
    awk '{ip[$1]++} END {for (i in ip) {print i,ip[i]}}' /data/log/nginx/access.log
    
    #统计/etc/fstab文件中每个文件系统类型出现的次数
    awk '/^UUID/{filesystem[$3]++}END{for (i in filesystem) {print i,filesystem[i]}}' /etc/fstab
    
    #统计指定文件中单词的出现次数
    awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab
    
    #统计出/etc/passwd文件中shell的种类和个数
    awk -F: '{shell[$NF]++}END{for(A in shell){print A,shell[A]}}' /etc/passwd
    
    重点解析一下这条命令:
    首先,shell[$NF]++这个语句。其中的$NF所代表的是一个字符串,即shell的类型。也就是说在这个数组中的元素名称是shell的名称。而后面的++是对这个数组进行赋值。因为在/etc/passwd 这个文件中的shell类型只有两种,即/bin/bash和/sbin/nologin。也就是说这个数组就只有两个元素,并且它的值是不断被更新的。其次,语句for(A in shell)是设定了A是数组shell中的坐标变量,即是A是元素的名称,shell[A]是数组的值。
    

    十二、awk的内置函数

    1.split(string, array [, fieldsep [, seps ] ])
    功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从0开始的序列;
    
    #example:
    netstat -ant | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count)print i,count[i]}'
    
    netstat -ant | awk '/:443/{split($5,clients,":");IP[clients[1]]++}END{for(i in IP){print IP[i],i}}' | sort -rn | head -50
    
    2.ength([string])
    功能:返回string字串中字符的个数
    
    3.substr(string, start [, length])
    功能:取string字符串中的子串,从start开始,取length个;start从1开始计数
    
    4.system(command)
    功能:执行系统command并将结果返回至awk命令
    
    5.systime()
    功能:取系统当前时间
    
    6.tolower(s)
    功能:将s中的所有字母转为小写
    
    7.toupper(s)
    功能:将s中的所有字母转为大写
    

    十三、常见用法汇总

    13.1 系统连接状态

    1.查看TCP连接状态
    netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
    
    netstat -n | awk '/^tcp/ {++state[$NF]};END {for(i in state) print i, state[i]}'
    
    netstat -n | awk '/^tcp/ {++state[$NF]}; END {for(i in state) print i,"	",state[i]}'
    
    netstat -n |awk '/^tcp/ {print $NF}'|sort|uniq -c|sort -rn
    
    netstat -ant | awk '{print $NF}' | grep -v '[a-z]' | sort | uniq -c
    
    2.查找请求数前20个IP(常用于查找攻来源):
    
    netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
    
    netstat -ant |awk '/:80/{split($5,ip,":");++A[ip[1]]}END{for(i in A) print A[i],i}' |sort -rn|head -n20
    
    3.用tcpdump嗅探80端口的访问看看谁最高
    
    tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -20
    
    4.查找较多time_wait连接
    
    netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20
    
    5.找查较多的SYN连接
    
    netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | more
    
    6.根据端口列进程
    
    netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1
    netstat -tnlp | awk '/22/{split($NF,port,"/");d[port[1]]++}END{for(i in d)print i}'
    

    13.2 网站日志分析

    1.获得访问前10位的ip地址
    
    cat /data/log/nginx/access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -10
    cat /data/log/nginx/access.log|awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}'
    
    2.访问次数最多的文件或页面,取前20
    
    cat /data/log/nginx/access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -20
    
    3.列出传输最大的几个exe文件(分析下载站的时候常用)
    
    cat /data/log/nginx/access.log |awk '($7~/.exe/){print $10 " " $1 " " $4 " " $7}'|sort -nr|head -20
    
    4.列出输出大于200000byte(约200kb)的exe文件以及对应文件发生次数
    
    cat /data/log/nginx/access.log |awk '($10 > 200000 && $7~/.exe/){print $7}'|sort -n|uniq -c|sort -nr|head -100
    
    5.如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
    
    cat /data/log/nginx/access.log |awk '($7~/.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -100
    
    6.列出最最耗时的页面(超过60秒的)的以及对应页面发生次数
    
    cat /data/log/nginx/access.log |awk '($NF > 60 && $7~/.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100
    
    7.列出传输时间超过 30 秒的文件
    
    cat access.log |awk '($NF > 30){print $7}'|sort -n|uniq -c|sort -nr|head -20
    
    8.统计网站流量(G)
    
    cat /data/log/nginx/access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'
    
    9.统计404的连接
    
    awk '($9 ~/404/)' /data/log/nginx/access.log | awk '{print $9,$7}' | sort
    
    10. 统计http status
    
    cat /data/log/nginx/access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
    cat /data/log/nginx/access.log |awk '{print $9}'|sort|uniq -c|sort -rn
    
    10.蜘蛛分析,查看是哪些蜘蛛在抓取内容。
    
    /usr/sbin/tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
    

    13.3 数据库

    /usr/sbin/tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | egrep -i 'SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER|CALL'
    

    13.4 系统Debug分析

    1.调试命令
    strace -p pid
    2.跟踪指定进程的PID
    gdb -p pid
    

    13.5 其他

    #统计某个文件夹下的文件占用的字节数
    ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size}'
    
    #如果以M为单位显示
    ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print "[end]size is ", size/1024/1024,"M"}'
    注意,统计不包括文件夹的子目录。
    
    #统计某个文件夹下的文件占用的字节数,过滤4096大小的文件(一般都是文件夹)
    ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
    
    #显示/etc/passwd的账户
    awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i in name) {print i,name[i]}}' /etc/passwd
    
    #AWK 的 hello world 程序为:
    BEGIN { print "Hello, world!" }
    
    #打印九九乘法表
    seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"
    ":"	")}'
    
    #results
    1x1=1
    1x2=2   2x2=4
    1x3=3   2x3=6   3x3=9
    1x4=4   2x4=8   3x4=12  4x4=16
    1x5=5   2x5=10  3x5=15  4x5=20  5x5=25
    1x6=6   2x6=12  3x6=18  4x6=24  5x6=30  6x6=36
    1x7=7   2x7=14  3x7=21  4x7=28  5x7=35  6x7=42  7x7=49
    1x8=8   2x8=16  3x8=24  4x8=32  5x8=40  6x8=48  7x8=56  8x8=64
    1x9=9   2x9=18  3x9=27  4x9=36  5x9=45  6x9=54  7x9=63  8x9=72  9x9=81
    

    欢迎留言,持续汇总。。。

     

  • 相关阅读:
    Java 线程池概念、原理、简单实现
    Java 中的等待唤醒机制透彻讲解
    Java 多线程安全问题简单切入详细解析
    理解 Java 多线程
    Java 异常的处理
    Android MediaPlayer的生命周期
    Node.js 撸第一个Web应用
    Android简易实战教程--第三十四话《 自定义SeekBar以及里面的一些小知识》
    使用Intent传递对象
    Android 异步查询框架AsyncQueryHandler的使用
  • 原文地址:https://www.cnblogs.com/joshua317/p/15354224.html
Copyright © 2020-2023  润新知