美文网首页
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