• linux--三剑客 grep sed awk 用法


    正则表达式
           转义符,将特殊字符进行转义,忽略其特殊意义 
    ^       匹配行首,awk中,^则是匹配字符串的开始  
    $       匹配行尾,awk中,$则是匹配字符串的结尾
    ^$      表示空行 
    .       匹配除换行符
    之外的任意单个字符 
    .*      匹配所有
    [ ]     匹配包含在[字符]之中的任意一个字符 
    [^ ]    匹配[^字符]之外的任意一个字符 
    [ - ]   匹配[]中指定范围内的任意一个字符 
    ?       匹配之前的项1次或者0次 
    +       匹配之前的项1次或者多次 
    *       匹配之前的项0次或者多次, .* 
    ()      匹配表达式,创建一个用于匹配的子串 
    { n }   匹配之前的项n次,n是可以为0的正整数 
    {n,}    之前的项至少需要匹配n次 
    {n,m}   指定之前的项至少匹配n次,最多匹配m次,n<=m 
    |       交替匹配|两边的任意一项ab(c|d)匹配abc或abd 
    cx	匹配由x指明的控制字符。例如, cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
    f	匹配一个换页符。等价于 x0c 和 cL。
    
    	匹配一个换行符。等价于 x0a 和 cJ。
    
    	匹配一个回车符。等价于 x0d 和 cM。
    s	匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f
    
    	v]。注意 Unicode 正则表达式会匹配全角空格符。
    S	匹配任何非空白字符。等价于 [^ f
    
    	v]。
    		匹配一个制表符。等价于 x09 和 cI。
    v	匹配一个垂直制表符。等价于 x0b 和 cK。
    
    特定字符
    >[[:space:]]    空格
     
    [[:digit:]]     [0-9]
     
    [[:lower:]]     [a-z]
     
    [[:upper:]]     [A-Z]
     
    [[:alpha:]]     [a-Z]
     
    

    grep 简单用法

    grep -n -A 2 "Failed" /var/log/secure 打印出符合内容的下两行和行号
     
    grep -n -B 2 "Failed" /var/log/secure 打印出符合内容的上两行和行号
     
    grep -n -C 2 "Failed" /var/log/secure 打印出符合内容的上下两行和行号
     
    grep -ni "[a-z]" /etc/passwd           统计所有带字母的行和行号
     
    grep -n ^$ file.txt                   打印空行的行号 
     
    grep -n . file.txt                    打印有内容的行和行号
     
    grep -n ^$ aa.txt                     打印空行的行和行号
     
    grep -v root /etc/passwd              打印不带root的行
     
    grep -E "a|b" /etc/passwd             打印带有a或者b的行
     
    grep -i root /etc/passwd              打印root,不区分大小写
     
    grep -R root /etc                     递归查找etc下有root的行
     
    grep -c . /etc/passwd                 统计行号
     
    grep "[0-9]" li.txt           匹配数字所在的行"[0-9]"
    
    grep -o "8*" l.txt            精确匹配到8
    
    grep -E "8{1,}" l.txt       至少1次或1次以上8
    
    

    sed文本处理

    sed是一个流编辑器, 非交互式的编辑器,它一次处理一行内容.
    处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)
    接着用 sed 命令处理缓冲区中的内容,处理完成后, 把缓冲区的内容送往屏幕。
    接着处理下一行,这样不断重复,直到文件末尾。
    文件内容并没有改变,除非你 使用重定向存储输出。
    Sed 要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等

    sed 命令格式
    sed [options] 'command' file(s)
    sed主要选项参数
    
    -e 允许多项编辑
     
    -n 取消默认的输出
     
    -i 直接修改对应文件
     
    -r 支持扩展元字符
    
    

    sed内置命令参数

    a  在当前行后添加一行或多行
     
    i   在当前行之前插入文本
     
    n   读入下一输入行,从下一条命令进行处理
     
    c   在当前行进行替换修改
     
    d   在当前行进行删除操作
     
    p   打印匹配的行或指定行
     
    !   对所选行以外的所有行应用命令
     
    h   把模式空间里的内容重定向到暂存缓冲区
     
    H   把模式空间里的内容追加到暂存缓冲区
     
    g   取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容
     
    G   取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后面
     
    

    简单用法

    sed -n ‘nd’ 删除农行 
    sed -n ‘/string/d’  删除匹配内容
    sed -n ‘/string/!d’  删除不是匹配的内容
    sed -n ‘2s###gp’  第2行的替换
    sed -n '1,5p'   打印1到5行
    sed -n '/aaa/,/bbb/p' 打印aaa到bbb的行,使用与d删除
    sed -n '/aaa/,10p' 打印aaa到10行
    sed -r ‘s#()#1#gp’ 后项引用,适用于组合命令|bash
    sed -r 's#(Roo)#1-alice#g' passwd  后向引用
    ifconfig eth0|sed -n '2p'|sed -r 's#(^.et) (.) (net.*$)#2#g'  后向引用
    sed ‘s#n#x#’ 取消了贪婪,替换每一行的第一个
    sed s#^#.*
    ##g   
    换行符,可以直接开头#的行,删除行
    sed  -n = 123  显示行号
    sed  -n '/./ =' 123 显示有内容的行号
    sed  -n '/^$/=' 123 显示空行的行号
    sed -i '/^$/d' file 删除空喊 
    sed -i '/aaa/c bbb' 将匹配ccc的行替换成bbb
    sed -i '/aaa/!d' 删除不是aaa的行
    sed '1,4i hahaha' yum.log 在第一和第4行每行之前插入哈哈哈,a是之后
    sed -e '1,5d' -e '=' -e 's/reboot/shutdown/g'  删除1到5行,然后替换
    sed -n '$p' file 打印文件最后一行
    sed "s/^/$RANDOM.rmvb_/g" #sed命令使用双引号的情况下,使用$var直接引用
    sed -n '/[^dinghua]/p' 1.txt 取不是dinghua的行
    sed -i.bak 's#2#3#g' 1.txt 改变的同时,将源文件拷贝成bak文件,防止修改错误
    sed -r '3!d' /etc/hosts   除了第三行,其他全部删除
    sed -r '/^[ 	]#/d' file   删除配置文件中含有tab键的注释行
    sed '/^#/d' file 删除配置文件中#号开头的注释行, 如果碰到tab或空格是无法删除
    sed -r '/^[ 	]$/d' file  删除无内容空行
     sed -r '/^[ 	]#/d; /^[ 	]$/d' vsftpd.conf 删除注释行及空行
    sed -r '/^[ 	]#|^[ 	]$/d' /etc/vsftpd/vsftpd.conf 删除注释行及空行
    sed -r '/^[ 	]*($|#)/d' /etc/vsftpd/vsftpd.conf  删除注释行及空行
    sed '2,6s/^/#/' passwd   将第二行到第六行加上注释信息
    sed -r '2,6s/.*/#&/' passwd  将第二行到第六行最前面添加#注释符
    
    

    w:写文件命令

    sed -n '/root/w newfile' passwd    将newfile中包含root的行写入passwd
    sed -n '2w newfile' passwd    将newfile中的第二行包含root的行写入passwd
    

    n:获取一下行命令

    匹配root的行, 删除root行的下一列
    [root@Shell ~]# sed '/root/{n;d}' passwd
    替换匹配root行的下一列
    [root@Shell ~]# sed '/root/{n; s/bin/test/}' passwd
    

    以上为sed的常规用法,需要掌握

    sed的高级用法

    暂存和取用命令h H g G
    将第一行的内容写入到暂存区, 替换最后一行的内容
    [root@Shell ~]# sed '1h;$g' /etc/hosts
    
    将第一行的写入到暂存区, 在最后一行调用暂存区的内容
    [root@Shell ~]# sed '1h;$G' /etc/hosts
    
    将第一行的内容删除但保留至暂存区, 在最后一行调用暂存区内容追加至于尾部
    [root@Shell ~]# sed -r '1{h;d};$G' /etc/hosts
    
    将第一行的内容写入至暂存区, 从第二行开始进行重定向替换
    [root@Shell ~]# sed -r '1h;2,$g' /etc/hosts
    
    将第一行的内容写入至暂存区, 从第二行开始进行重定向替换
    [root@Shell ~]# sed -r '1h;2,$g' /etc/hosts
    
    将第一行重定向至暂存区, 2-3行追加至暂存区, 最后追加调用暂存区的内容
    [root@Shell ~]# sed -r '1h; 2,3H; $G' /etc/hosts
    

    AWK

    awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。
    awk数据可以来自标准输入、一个或多个文件,或其它命令的输出。
    awk通常是配合脚本进行使用, 是一个强大的文本处理工具。

    awk 的处理数据的方式

    1.进行逐行扫描文件, 从第一行到最后一行
    2.寻找匹配的特定模式的行,在行上进行操作
    3.如果没有指定处理动作,则把匹配的行显示到标准输出
    4.如果没有指定模式,则所有被操作的行都被处理

    Awk工作原理

    awk -F: '{print $1,$3}' /etc/passwd
    1.awk将文件中的每一行作为输入, 并将每一行赋给内部变量$0, 以换行符结束
    2.awk开始进行字段分解,每个字段存储在已编号的变量中,从$1开始[默认空格分割]
    3.awk默认字段分隔符是由内部FS变量来确定, 可以使用-F修订
    4.awk行处理时使用了print函数打印分割后的字段
    5.awk在打印后的字段加上空格,因为$1,$3 之间有一个逗号。逗号被映射至OFS内部变量中,称为输出字段分隔符, OFS默认为空格.
    6.awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕.

    awk简单用法
    $NF 最后一列
    awk ‘//’
    awk '{print $n}'  $NF 最后一列
    awk ‘NR==1’ NR>2 && NR <3  取行,固定行和范围行
    awk 'END{print NR}' 1.txt  取总行数  END是最后一行
    awk 'END{print $0}' passwd.txt  取最后一行
    awk -F '[, ]' file  ,和空格都是分隔符 '[, ]+'不但作为分隔符,也可以整体使用
    awk '{NR==1 {print $n}}' file   取文件第一行,然后打印出列
    awk 'BEGIN{print 1/3}'   对1/3进行运算,相当于计算器
    awk '!/str/' file !取反 和sed不一样,放在匹配的前面
    df |awk '//$/ {if ($3>50000) print $4}' 判断大于多少则输出什么内容 command |awk 'pattern {action}'
    awk '{print $0}' /etc/passwd  $0保存当前记录的内容
    awk '{print FNR,$0}' /etc/passwd /etc/hosts  2个文件分别的行号都输出
    awk '{print NR,$0}' /etc/passwd /etc/hosts   2个文件的行号叠加
    awk -F'[ :	]' '{print $1,$2,$3}' /etc/passwd  以空格冒号tab作为字段分割
    ### OFS指定输出字段分隔符
    ### 逗号映射为OFS, 初始情况下OFS变量是空格
    awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd
    awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2}' /etc/passwd
    awk -F: 'BEGIN{RS=" "} {print $0}' /etc/hosts  RS输入记录分隔符,默认为换行符,将空格换成了换行 RS=" ",RS是换行
    [root@Shell ~]# awk -F: 'BEGIN{ORS=" "} {print $0}' /etc/hosts ORS将文件以空格为分割每一行合并为一行[了解]
    
    printf 函数
    awk -F: '{printf "%-15s %-10s %-15s
    ", $1, $2, $3}' /etc/passwd
    %s 字符类型
    %d 数值类型
    占 15 字符
    
    表示左对齐,默认是右对齐
    printf 默认不会在行尾自动换行,加
    
    

    Awk模式动作
    awk语句都由模式和动作组成。
    模式部分决定动作语句何时触发及触发事件。
    如果省略模式部分,动作将时刻保持执行状态。模式可以是条件语句或复合语句或正则表达式。

    1.正则表达式
    匹配记录(整行)
    [root@Shell ~]# awk '/^root/' /etc/passwd
    [root@Shell ~]# awk '$0 ~ /^root/' /etc/passwd
    
    匹配字段:匹配操作符(~ !~)
    [root@Shell ~]# awk '$1~/^root/' /etc/passwd
    [root@Shell ~]# awk '$NF !~ /bash$/' /etc/passwd
    
    2.比较表达式
    比较表达式采用对文本进行比较,只有当条件为真,才执行指定的动作。
    比较表达式使用关系运算符,用于比较数字与字符串。
    
    运算符     含义         示例 
     
    <       小于          x<y 
     
    <=      小于或等于     x<=y 
     
    ==      等于          x==y 
     
    !=      不等于         x!=y
    >=      大于等于        x>=y
    >       大于          x>y
    
    uid为0的列出来
    [root@Shell ~]# awk -F ":" '$3==0' /etc/passwd
    
    uid小于10的全部列出来
    [root@Shell ~]# awk -F: '$3 < 10' /etc/passwd
    
    用户登陆的shell等于/bin/bash
    [root@Shell ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd
    
    第一列为alice的列出来
    [root@Shell ~]# awk -F: '$1 == "alice" ' /etc/passwd
    
    为alice的用户列出来
    [root@Shell ~]# awk -F: '$1 ~ /alice/ ' /etc/passwd
    [root@Shell ~]# awk -F: '$1 !~ /alice/ ' /etc/passwd
    
    磁盘使用率大于多少则,则打印可用的值
    [root@Shell ~]# df |awk '//$/'|awk '$3>1000000 {print $4}'
    
    3.条件表达式
    [root@Shell ~]# awk -F: '$3>300 {print $0}' /etc/passwd
    [root@Shell ~]# awk -F: '{if($3>300) print $0}' /etc/passwd
    [root@Shell ~]# awk -F: '{if($3>5555){print $3} else {print $1}}' /etc/passwd
    
    4.运算表达式
    
    [root@Shell ~]# awk -F: '$3 * 10 > 500000' /etc/passwd
    [root@Shell ~]# awk -F: 'BEGIN{OFS="--"} { if($3*10>50000) {print $1,$3} } END {print "打印ok"}' /etc/passwd
    [root@Shell ~]# awk '/southem/{print $5 + 10}' datafile 
    [root@Shell ~]# awk '/southem/{print $5 + 10.56}' datafile
    [root@Shell ~]# awk '/southem/{print $8 - 10}' datafile 
    [root@Shell ~]# awk '/southem/{print $8 / 2 }' datafile  
    [root@Shell ~]# awk '/southem/{print $8 * 2 }' datafile 
    [root@Shell ~]# awk '/southem/{print $8 % 2 }' datafile
    
    5.逻辑操作符和复合模式
    &&逻辑与 || 逻辑或 !逻辑非
    匹配用户名为root并且打印uid小于15的行
    [root@Shell ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd
    
    匹配用户名为root或uid大于5000
    [root@Shell ~]# awk -F: '$1~/root/ || $3>=5000' /etc/passwd
    
    
    统计系统用户数量
    [root@Shell ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd
    统计普通用户数量
    [root@Shell ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd
    

    Awk循环语句

    [root@Shell ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++} }'
    [root@Shell ~]# awk -F: '{i=1; while(i<=NF){print $i; i++}}' /etc/passwd
    [root@Shell ~]# awk -F: '{i=1; while(i<=10) {print $0; i++}}' /etc/passwd
    [root@Shell ~]#cat b.txt
    111 222
    333 444 555
    666 777 888 999
    [root@Shell ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt
    1.4.11.2    for循环
    C 风格 for
    [root@Shell ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }' 
    将每行打印 10 次
    [root@Shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd
    [root@Shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd 
    [root@Shell ~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i} }' passwd
    

    awk数组概述

    统计/etc/passwd中各种类型shell 的数量*
    awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd
    站访问状态统计<当前时实状态ss>*
    [root@Shell ~]# ss -an|awk '/:80/{tcp[$2]++} END {for(i in tcp){print i,tcp[i]}}'
    
    统计当前访问的每个IP的数量<当前时实状态 netstat,ss>*
    [root@Shell ~]# ss -an|awk -F ':' '/:80/{ips[$(NF-1)]++} END {for(i in ips){print i,ips[i]}}'
    
    Awk数组案例
    Nginx日志分析,日志格式如下:
     
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
     
    52.55.21.59 - - [25/Jan/2018:14:55:36 +0800] "GET /feed/ HTTP/1.1" 404 162 "https:www.google.com/" "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52" "-"
    统计2018年01月25日,当天的PV量*
    [root@Shell ~]# grep "25/Jan/2018" log.bjstack.log |wc -l
    [root@Shell ~]# awk "/25/Jan/2018/" log.bjstack.log |wc -l
    [root@Shell ~]# awk '/25/Jan/2018/ {ips[$1]++} END {for(i in ips) {sum+=ips[i]} {print sum}}' log.bjstack.log
    统计15-19点的pv量
    [root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00 {print $0}"' log.bjstack.log |wc -l
    
    统计2018年01月25日,一天内访问最多的10个IP*
    [root@Shell ~]# awk '/25/Jan/2018/ {ips[$1]++} END {for(i in ips){ print ips[i],i}}' log.bjstack.log |sort -rn|head
    
    统计15-19点访问次数最多的10个IP
    [root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00"' log.bjstack.log |awk '{ips[$1]++} END {for(i in ips){print ips[i],i}}'|sort -rn|head
    
    统计2018年01月25日,访问大于100次的IP*
    [root@Shell ~]# awk '/25/Jan/2018/ {ips[$1]++} END {for(i in ips){if(ips[i]>10){print i,ips[i]}}}' log.bjstack.log
    
    统计2018年01月25日,访问最多的10个页面($request top 10)*
    [root@Shell ~]# awk '/25/Jan/2018/ {request[$7]++} END {for(i in request){print request[i],i}}' log.bjstack.log |sort -rn|head
    
    统计2018年01月25日,每个URL访问内容总大小($body_bytes_sent)*
    [root@Shell ~]# awk '/25/Jan/2018/ {request[$7]++;size[$7]+=$10} END {for(i in request){print request[i],i,size[i]}}' log.bjstack.log |sort -rn|head
    
    统计2018年01月25日,每个IP访问状态码数量($status)*
    [root@Shell ~]# awk '{ip_code[$1 " " $9]++} END {for(i in ip_code){print ip_code[i],i}}' log.bjstack.log|sort -rn|head
    
    统计2018年01月25日,访问状态码为404及出现的次数($status)*
    [root@Shell ~]# grep "404" log.bjstack.log |wc -l
    [root@Shell ~]# awk '{if($9=="404") code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
    
    统计2018年01月25日,8:30-9:00访问状态码是404*
    [root@Shell ~]# awk '$4>="[25/Jan/2018:15:00:00" && $4<="[25/Jan/2018:19:00:00" && $9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
    [root@Shell ~]# awk '$9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
    
    统计2018年01月25日,各种状态码数量,统计状态码出现的次数
    [root@Shell ~]# awk '{code[$9]++} END {for(i in code){print i,code[i]}}' log.bjstack.log
    [root@Shell ~]# awk '{if($9>=100 && $9<200) {i++}
    else if ($9>=200 && $9<300) {j++}
    else if ($9>=300 && $9<400) {k++}
    else if ($9>=400 && $9<500) {n++}
    else if($9>=500) {p++}}
    END{print i,j,k,n,p,i+j+k+n+p}' log.bjstack.log
    
    
  • 相关阅读:
    setInterval和setTimeOut方法—— 定时刷新
    json
    开发者必备的火狐插件
    C#泛型类和集合类的方法
    jQuery几种常用方法
    SQL语句优化技术分析
    索引的优点和缺点
    Repeater使用技巧
    jQuery 表格插件
    利用WebRequest来实现模拟浏览器通过Post方式向服务器提交数据
  • 原文地址:https://www.cnblogs.com/dinghc/p/13558555.html
Copyright © 2020-2023  润新知