美文网首页
shell 文本处理三剑客

shell 文本处理三剑客

作者: 是立品啊 | 来源:发表于2020-07-16 22:30 被阅读0次

    grep

    语法

    grep [option] [pattern][fiel1,fiel2....]
    some command | grep [option][pattern]
    

    语法解释

    用法: grep [选项]... PATTERN [FILE]...

    • 在每个 FILE 或是标准输入中查找 PATTERN。
    • 默认的 PATTERN 是一个基本正则表达式(缩写为 BRE)。
      例如: grep -i 'hello world' menu.h main.c
    grep root /etc/passwd 
    cat /etc/passwd | grep "root"
    

    参数

    grep -c root /etc/passwd : -c统计匹配到了多少行
    grep -r author ./:-r递归当前文件下含有author的文件
    grep -r -n author ./:-n 显示行号
    grep -r -n -l author ./:-l只展示文件名
    grep -E "w{3}" /etc/passwd :加-E可匹配复杂的正则
    grep "w.." /etc/passwd-E参数,可匹配简单的正则,复杂的不行

    案例

    • 取出所有状态为nologin的用户名
    grep "nologin" /etc/passwd | cut -d ":" -f1
    
    • jack执行的 等级为 CRITICAL 的日志的条数
    grep "jack" testcases.log | grep  "CRITICAL" | wc -l
    
    • >>&> 命令的输出丢弃,&>包含错误信息也一并丢弃
    grep "${USER}" /etc/passwd >> /dev/null && echo "${USER}存在" || echo "${USER}不存在"
    grep "${USER}" /etc/passwd &> /dev/null && echo "${USER}存在" || echo "${USER}不存在"
    

    sed

    • 流编辑器,最文件逐行进行处理

    语法

    sed [option] "pattern command" file
    some command | sed [option] "pattern command" 
    

    选项option

    -n 只打印模式匹配的行
    -f 加载存放动作的文件
    -r 支持拓展正则
    -i直接修改文件

    pattern模式

    • 5 只处理第5行
    • 5,10 只处理第5行到第10行
    • /pattern1/ 只处理能匹配pattern1的行
    • /pattern1/,/pattern2/只处理匹配pattern1的行到匹配pattern2的行

    command命令

    • 查询
      • p
        • 打印
    • 新增
      • a
        • 在匹配行后新增
    sed  'a "添加的内容"' passwd
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    root:x:0:0:root:/root:/bin/bash
    "添加的内容"
    bin:x:1:1:bin:/bin:/sbin/nologin
    "添加的内容"
    
    
    sed  '/jenkins/,/grafana/ a "python' passwd
    
    • i
      • 在匹配行前新增
    sed 'i "添加的内容在匹配行之前"' passwd
    "添加的内容在匹配行之前"
    root:x:0:0:root:/root:/bin/bash
    "添加的内容在匹配行之前"
    bin:x:1:1:bin:/bin:/sbin/nologin
    
    • r
      • 外部文件读入,行后新增
    sed '/jenkins/ r test.txt' passwd
    >>>>>>>>>>>>>>>>>>>>>>>>>>>
    jenkins:x:990:986:Jenkins Automation Server:/var/lib/jenkins:/bin/false
    python is very easy
    
    • w
      • 匹配行写入外部文件
    sed -n '/\/sbin\/nologin/ w one_file.txt' passwd
    
    • 删除
      • d
    sed '/jenkins/ d ' passwd 删掉含有Jenkins的行
    
    • 修改
      • s/old/new/
        • 只修改匹配行中第一个old
      • s/old/new/g
        • 修改匹配行中所有的old
      • s/old/new/ig
        • 忽略大小写
    sed '3,9 s/bin/BIN/' passwd
    >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
         1  root:x:0:0:root:/root:/bin/bash
         2  bin:x:1:1:bin:/bin:/sbin/nologin
         3  daemon:x:2:2:daemon:/sBIN:/sbin/nologin
         4  adm:x:3:4:adm:/var/adm:/sBIN/nologin
         5  lp:x:4:7:lp:/var/spool/lpd:/sBIN/nologin
         6  sync:x:5:0:sync:/sBIN:/bin/sync
         7  shutdown:x:6:0:shutdown:/sBIN:/sbin/shutdown
         8  halt:x:7:0:halt:/sBIN:/sbin/halt
         9  mail:x:8:12:mail:/var/spool/mail:/sBIN/nologin
    
    sed 'p' /etc/passwd 默认会打印两遍
    

    案例

    sed -n 'p' /etc/passwd 只打印模式匹配的行
    sed -n '2 p' passwd 查询passwd的第二行
    sed -n '32,34 p' passwd  查询 Passwd文件的32到34行
    sed -n "/mail/ p" passwd 查询含有mail的行
    
    sed -n "/^jenkins/,/^grafana/ p" passwd   查询 Jenkins开头的行到 grafana 的行
    
    • 如果没有加-i参数,都不是真正的新增删除

    综合案例:查看CPU核数

    [root@VM_0_11_centos ~]# cat /proc/cpuinfo | sed -n "/cpu cores/ p " | uniq
    cpu cores   : 1
    
    [root@VM_0_11_centos ~]# cat /proc/cpuinfo | sed -n "/cpu cores/ p " | uniq | cut -d " " -f1
    cpu
    [root@VM_0_11_centos ~]# cat /proc/cpuinfo | sed -n "/cpu cores/ p " | uniq | cut -d " " -f2
    cores   :
    [root@VM_0_11_centos ~]# cat /proc/cpuinfo | sed -n "/cpu cores/ p " | uniq | cut -d " " -f3
    

    awk

    • 文本处理工具,针对于列(字段)处理,处理数据并生成结果报告
    • 两种形式
      awk 'BEGIN{}pattern{commands}END{}'file
      some command | awk

    格式

    • BEGIN{} 处理文本之前执行
    • pattern 匹配模式
    • {commands} 处理的命令
    • END{} 处理文本之后执行

    内置变量

    内置变量 含义
    $0 整行
    $1-$n 当前行第几个字段
    NF(number field) 当前行字段数
    NR(number row) 当前行行号
    FS(Field separator) 输入字段分隔符,默认为空格或tab键
    RS(row separator) 输入行分隔符,默认为回车符
    OFS(output field separator) 输出字段分隔符,默认为空格
    ORS(output row separator) 输出行分隔符,默认为回车符

    基础使用

    [root@VM_0_11_centos ~]# cat info.txt
    name    gender   age     love
    jack     man     17  java
    luck     women   20  python
    hank     man     30  ui
    
    [root@VM_0_11_centos ~]# awk '{print $1}' info.txt
    name
    jack
    luck
    hank
    [root@VM_0_11_centos ~]# awk '{print $2}' info.txt
    gender
    man
    women
    man
    
    [root@VM_0_11_centos ~]# awk '{print NF}' info.txt
    4
    4
    4
    4
    [root@VM_0_11_centos ~]# awk '{print NR}' info.txt
    1
    2
    3
    4
    [root@VM_0_11_centos ~]# awk '{print $NF}' info.txt
    love
    java
    python
    ui
    
    awk 'BEGIN{FS=":"}{print $1}' /etc/passwd
    awk 'BEGIN{FS=":"}{print $NF}' /etc/passwd   冒号分割,打印最后一列
    awk 'BEGIN{FS=":"}{print $(NF-1)}' /etc/passwd  冒号分割,打印倒数第二列
    

    printf

    %s 字符串
    %d 十进制数字
    %f浮点数

    修饰符

    +右对齐
    -左对齐

    awk 'BEGIN{FS=":"}{printf "%20s %20s\n" , $1 , $NF}' /etc/passwd
    awk 'BEGIN{FS=":"}{printf "%-20s %-20s\n" , $1 , $NF}' /etc/passwd  左对齐
    awk 'BEGIN{FS=":"}/mail/{printf "%-20s%-20s\n", $1,$NF}' /etc/passwd  加匹配模式,只处理匹配到的行
    mail                /sbin/nologin
    
    awk 'BEGIN{FS=":"}/ntp/,/sshd/{printf "%-20s%-20s\n", $1,$NF}' /etc/passwd
    awk 'BEGIN{FS=":"} $4 > 100 {printf "%-20s%-20s\n", $1,$NF}' /etc/passwd
    awk 'BEGIN{FS=":"} $1=="grafana" {printf "%-20s%-20s\n", $1,$NF}' /etc/passwd
    grafana             /sbin/nologin
    
    awk 'BEGIN{FS=":"} $1 ~ "g" {printf "%-20s%-20s\n", $1,$NF}' /etc/passwd
    games               /sbin/nologin
    libstoragemgmt      /sbin/nologin
    syslog              /bin/false
    gitlab-www          /bin/false
    git                 /bin/sh
    gitlab-redis        /bin/false
    gitlab-psql         /bin/sh
    gitlab-prometheus   /bin/sh
    grafana             /sbin/nologin
    
    awk 'BEGIN{FS=":"} $1 ~ "g" {count++;printf "%-20s%-20s\n", $1,$NF}END{printf "%-20s%-20s\n","total",count}' /etc/passwd
    games               /sbin/nologin
    libstoragemgmt      /sbin/nologin
    syslog              /bin/false
    gitlab-www          /bin/false
    git                 /bin/sh
    gitlab-redis        /bin/false
    gitlab-psql         /bin/sh
    gitlab-prometheus   /bin/sh
    grafana             /sbin/nologin
    total               9
    
    
    
    awk 'BEGIN{FS=":";printf "%-20s%-20s\n","username","shell"} $1 ~ "g" {count++;printf "%-20s%-20s\n", $1,$NF}END{printf "%-20s%-20s\n","total",count}' /etc/passwd
    username            shell
    games               /sbin/nologin
    libstoragemgmt      /sbin/nologin
    syslog              /bin/false
    gitlab-www          /bin/false
    git                 /bin/sh
    gitlab-redis        /bin/false
    gitlab-psql         /bin/sh
    gitlab-prometheus   /bin/sh
    grafana             /sbin/nologin
    total               9
    
    • 变量count不需要定义,直接使用
    • begin和end使用

    命令写在文件中

    以上命令写在文件中
    user_info.awk

    BEGIN{
        FS=":"
        printf "%-20s%-20s\n","username","shell"
    }
    
    {
        if($1 ~ "g"){
            count++
            printf "%-20s%-20s\n", $1,$NF
            }
    }
    
    END{
        printf "%-20s%-20s\n","total",count
    }
    

    执行命令

    awk -f user_info.awk /etc/
    

    实战

    • 统计每位测试人员执行用例的总数
    基础版
    BEGIN{
    printf "%-20s%-20s\n","测试人员","测试用例总数"
    }
    {
        if ($4 == "keyou"){
            keyou++
        }else if( $4 == "keke"){
            keke++
        }
    }
    END{
    printf "%-20s%-20s\n","keyou",keyou
    printf "%-20s%-20s\n","keke",keke
    }
    
    进阶版
    BEGIN{
    printf "%-20s%-20s\n","测试人员","测试用例总数"
    }
    {
       USERS[$4] +=1
    }
    END{
        for(u in USERS)
          printf "%-20s%-20d\n",u,USERS[u]
    }
    
    • 分别统计每位测试人员执行用例成功和失败的总数
    BEGIN{
    printf "%-20s%-20s%-20s\n","测试人员","成功用例总数","失败用例总数"
    }
    {
       if($5 == "Pass"){
       Success[$4] +=1
       }else{
        Fail[$4] +=1
       }
       USERS[$4] +=1
    }
    END{
        for(u in USERS)
          printf "%-20s%-20d%-20d\n",u,Success[u],Fail[u]
    }
    
    
    • 将1,2合同,同时分别统计每位测试人员执行用例CRITICAL,ERROR日志等级数以及所有的测试人员每项总数
    BEGIN{
    printf "%-20s%-20s%-20s%-20s%-20s\n","测试人员","成功用例总数","失败用例总数","Error用例数","Critical用例数"
    }
    {
       if($5 == "Pass"){
       Success[$4] +=1
       }else{
        Fail[$4] +=1
       }
    
       if($3 == "ERROR"){
       ERROR[$4] +=1
       }else{
        CRITICAL[$4] +=1
       }
    
       USERS[$4] +=1
    }
    END{
        for(u in USERS){
          ALL_ERRORS+=ERROR[u]
          ALL_CRITICAL+=CRITICAL[u]
          ALL_SUCCESS+=Success[u]
          ALL_FAIL+=Fail[u]
          printf "%-20s%-20d%-20d%-20d%-20d\n",u,Success[u],Fail[u],ERROR[u],CRITICAL[u]}
        printf "%-20s%-20d%-20d%-20d%-20d\n","total",ALL_SUCCESS,ALL_FAIL,ALL_ERRORS,ALL_CRITICAL
    
    }
    
    >>>>>>>>>>>>>>>>>>>>>>>
    (venv)  ~/study/homework  awk -f awk_files/test4.awk testcases.log
    测试人员        成功用例总数  失败用例总数  Error用例数      Critical用例数   
    lemon               10840               4171                4403                10608               
    keke                10308               4318                2750                11876               
    keyou               6931                2445                2350                7026                
    youyou              10823               5262                3708                12377               
    youke               8446                4012                3058                9400                
    total               47348               20208               16269               51287 
    
    • 使用shell脚本实现,并显示菜单,选择不同的选项则打印不同的内容
    • 思路:先read,然后case分支

    相关文章

      网友评论

          本文标题:shell 文本处理三剑客

          本文链接:https://www.haomeiwen.com/subject/yaxvhktx.html