shell脚本文本三剑客grep,sed,awk

1.  正则表达式,又称正规表达式、常规表达式

    使用字符串来描述、匹配一系列符合某个规则的字符串

    正则表达式组成:

    普通字符包括大小写字母、数字、标点符号及一些其他符号。

    元字符是指在正则表达式中具有特殊意义的专用字符

    man 7 regex

    可以使用man手册帮助

2、元字符

   基础正则表达式常见元字符

(支持的工具:grep、egrep、sed、awk)

 

3、扩展正则表达式元字符

grep -E

字符作用
+表示匹配前面的子表达式1次以上
?表示匹配前面的子表达式0或者1次

( )

将括号里的内容看成一个整体
|

以或的方式匹配字符串

4. grep

格式:

grep [选项]… 查找条件 目标文件



-color=auto    对匹配到的文本着色显示
-m  #             匹配到#次后停止;匹配到#行后停止

-v                   显示没有被匹配到的行,即取反
-i                    忽略字符大小写
-n                  显示匹配到的行号
-c                   统计匹配到的行数
-o                  仅显示匹配到的字符串
-q                  静默模式,不输出任何信息
-A                  匹配到的行后#行也显示出来
-B                  匹配到的行前#行也显示出来
-C                 匹配到的行前后各#行也显示出来
-e                  实现多个选项间的逻辑or关系
-w                 匹配整个单词
-E                 扩展正则表达式,相当于egrep
-F                 不支持正则表达式,相当于fgrep
-f                   file根据模式文件,处理两个文件相同内容,把第一个文件作为匹配条件

-r                  递归目录,但不处理软链接
-R                 递归目录,处理软链接
 

实例:

统计当前主机的连接状态

 统计当前连接的主机数

5. sed的基本概念
sed是什么
sed编辑器时一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流
sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要存储在一个命令文本文件中。

sed编辑器的工作流程:
sed 的工作流程主要包括读取、执行和显示三个过程:

读取:  sed从输入流(文件、管道、标准输入)中读取一行内容并存储到临时的缓冲区中(又称模式            空间,pattern space )。
执行:默认情况下,所有的sed 命令都在模式空间中顺序地执行, 除非指定了行的地址,否则sed             命令将会在所有的行上依次执行。
显示:   发送修改后的内容到输出流(屏幕)。在发送数据后,模式空间将会被清空。在所有的文件内             容都被处理完成之前,上.述过程将重复执行,直至所有内容被处理完。
           在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。

注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,
除非是用重定向存储输出或者sed -i

sed命令的基本用法

格式:

sed [option]... 'script;script;...' [input  file...]
     选项         自身脚本语法         支持标准输入管道

常用选项:

-n          不输出模式空间内容到屏幕,即不自动打印
-e          多点编辑
-f           从指定文件中读取编辑脚本
-r,-E    使用扩展正则表达式
-i.bak     备份文件并原处编辑

4、sed脚本格式

单引号中间需要写脚本;脚本格式如下

利用具体操作,进一步熟悉sed 

(1)打印内容

 打印全部内容

sed ' '            #交互模式输入一行,自动打印一行相同的

sed -n ' '        #交互模式输入一行,关闭自动打印

sed -n ' p'      #加上p又恢复自动打印,与sed ' '相同

查看文件,打印全部内容 

sed    ' '    /etc/fatab

sed  -n  ' p'   /etc/fatab

 打印指定行内容 

sed -n '3p' /etc/fstab

打印第三行内容

 

ifconfig ens33 |sed -n '2,4p'

#打印网卡信息的2至4行

cat -n /etc/passwd |sed -n '2,+4p'

#打印第2至6行,即第二行开始往后四行

sed '3q' /etc/passwd

#打印三行后退出

打印最后一行,使用通配符$ 

sed -n '$p' /etc/passwd

支持正则表达式,打印范围内容

sed -n '//,//p' 文件名
#第一个//表示开头位置,第二个//表示结尾位置
 
#sed -n '/^b/,/^f/p' /etc/passwd
###     基本格式     '/表达式1/,/表达式2/p' (不要忘记打印)p  文件名

 过滤关键字

 

 

sed -n '2,/root/p' /etc/passwd

#从第二行开始,找到root为止

sed -n '/root/,3p' /etc/passwd

#找到第三个root位置

打印文本的奇数和偶数行 

 

 (2)删除内容

删除指定行

 

 删除指定多行 

 

删除空行

 

 删除以指定字符结尾的行及取反

 

 删除行,并原文备份

(3) 插入内容

在指定行后插入

插入空行,修改文件的换行,要多加一个\

 

(4)替换内容 

 

 

(5)搜索替换 

格式:格式:sed 行范围 s/旧字符串/新字符串/替换标记

替换标记:

  • 数字:表明新字符串将替换第几处匹配的地方

  • g : 表明新字符串将会替换所有匹配的地方

  • p : 打印与替换命令匹配的行,与 -n 一起使用

  • w 文件 :将替换的结果写到文件中

5.修改selinux开机不自启配置文件 

sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

修改全局,后面加g

sed -i 's/root/admin/g' /etc/passwd

#将全局出现的root修改为admin

查找几点到几点之间的日志

sed -n '/2023:08:09/,/2023:09:42:37/p' access_log

 6.分组调用

调用分组段


分组使用()(),调用第一段使用\1
echo 11aaxx |sed -r 's/(11)(aa)(xx)/\1/'
 
调用第2个分组
echo 11aaxx |sed -r 's/(11)(aa)(xx)/\2/'
 
调用第1个和第二个分组
echo 11aaxx |sed -r 's/(11)(aa)(xx)/\1\2/'

7. 提取IP地址 

ifconfig ens33 |sed -rn '2s/.*(inet) ([0-9.]+)  (netmask) ([0-9.]+)  (broadcast) ([0-9.]+).*/\2/p'

8. awk

(1)什么是awk

awk:Aho, Weinberger, Kernighan,报告生成器,格式化文本输出,GNU/Linux发布的AWK目前由自由软件基金会(FSF)进行开发和维护,通常也称它为 GNU AWK

有多种版本:

AWK:原先来源于 AT & T 实验室的的AWK

NAWK:New awk,AT & T 实验室的AWK的升级版

GAWK:即GNU AWK。所有的GNU/Linux发布版都自带GAWK,它与AWK和NAWK完全兼容

GNU AWK 用户手册文档 

The GNU Awk User’s Guide

 在 Linux/UNIX 系统中,awk 是一个功能强大的编辑工具,逐行读取输入文本,默认以空格或tab键作为分隔符作为分隔,并按模式或者条件执行编辑命令。而awk比较倾向于将一行分成多个字段然后进行处理。AWK信息的读入也是逐行指定的匹配模式进行查找,对符合条件的内容进行格式化输出或者过滤处理,可以在无交互的情况下实现相当复杂的文本操作,被广泛应用于 Shell 脚本,完成各种自动化配置任务。

(2)工作原理

格式: 

 awk [options]  'program' var=value  file…

说明:

program通常是被放在单引号中,并可以由三种部分组成

  • BEGIN语句块

  • 模式匹配的通用语句块

  • END语句块

常见选项:

  • -F “分隔符” 指明输入时用到的字段分隔符,默认的分隔符是若干个连续空白符

  • -v var=value 变量赋值

Program格式:

pattern{action statements;..}  

pattern:决定动作语句何时触发及触发事件,比如:BEGIN,END,正则表达式等
action statements:对数据进行处理,放在{}内指明,常见:print, printf
output statements:print,printf
Expressions:算术,比较表达式等
Compound statements:组合语句
Control statements:if, while等
input statements

执行过程:

常见的内建变量(可直接用) 

 

9.结合简单示例,对awk进一步理解 

打印文本内容

  • awk可以将自动将多个空格压缩成一个空格

  • 打印字符串需要加双引号

打印磁盘已经使用情况 

df |awk '{print $5}'

 

打印字符串 

awk '{print "hello"}'

 

打印字符串确定文件有多少行

awk '{print "hello"}' /etc/fstab

awk '{print "hello"}' /etc/fstab |wc -l

cat /etc/fstab |wc -l

 根据$n以及NR提取字段

 提取ip地址

根据选项-F指定分隔符

打印/etc/passwd所有用户名

cat /etc/passwd|awk -F":" '{print $1}'

cat /etc/passwd|awk -F: '{print $1}'

打印多列内容

打印时逗号可以表示空格,如果使用“:”或者“+”,需要将特殊符号加上双引号当成字符串打印

cat /etc/passwd|awk -F: '{print $1,$3}'
指定冒号作为分隔符,打印第一列和第三列
cat /etc/passwd|awk -F: '{print $1":"$3}'
用冒号分隔开
cat /etc/passwd|awk -F: '{print $1"\t"$3}'

打印磁盘已经使用情况,去除%

  1. #使用两条awk命令

  2. df|awk '{print $5}'|awk -F% '{print $1}'

  3. #使用一条awk命令

  4. df|awk -F"[ %]+" '{print $5}'

  5. ##也可以使用( |%)代表或者

  6. df|awk -F"( |%)+" '{print $5}'

 取出文本中的ip地址及时间 

取出文本中的主机并放回

根据关键字提取所在行

提取/etc/passwd 以root开头的行 

cat /etc/passwd |awk -F":" '/^root/{print}' 

 提取/etc/passwd root所在的行 

      cat /etc/passwd |awk -F: '/root/{print}'

 提取/etc/passwd nologin结尾的行 

  1. cat /etc/passwd |awk -F":" '/nologin$/{print}'

  2. ##如果提取/sbin/nologin,则需要\转义/

  3. cat /etc/passwd |awk -F":" '/\/sbin\/nologin$/{print}'

使用BEGIN输出包含指定字符的行并统计有多行

  • BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;

  • awk再处理指定的文本,之后再执行END模式中指定的动作;

  • END{ } 语句块中,往往会放入打印结果等语句。

  1. #先定义变量x,表示执行多少次

  2. awk 'BEGIN {x=0};/\/bin\/bash$/;{x++};END{print x}' /etc/passwd

FS:指定每行文本的字段分隔符,默认为空格或制表符,与-F相同

        awk -v FS=: '{print $1FS$3}' /etc/passwd

NF:当前处理行的整行内容 

当前处理的行的字段个数

cat /etc/passwd |awk -F: '{print NF}'

 打印出每行最后一个字段 

cat /etc/passwd |awk -F: '{print $NF}'

打印出每行倒数第二个字段

cat /etc/passwd |awk -F: '{print $(NF-1)}'

NR:当前处理行的行号 

当前处理的行的行号

  NR==n代表行号等于什么

       awk -F: 'NR==2 {print $1}' /etc/passwd 

  NR%2==0取偶数行

       awk -F: 'NR%2==0 {print NR"\t"$1}' /etc/passwd

NR%2==1取奇数行 

       awk -F: 'NR%2==1 {print $1}' /etc/passwd

NR==1,NR==4取区间行 

        awk -F: 'NR==1,NR==4 {print $1}' /etc/passwd

取UID数值范围$n>1000 

  1. #取uid大于1000的行

  2. awk -F: '$3>1000 {print}' /etc/passwd

  3. #取uid大于等于1000的行

  4. awk -F: '$3>=1000 {print}' /etc/passwd