文章目录
三剑客与正则表达式的关系
三剑客就是普通的命令,有时把他们叫做工具。而正则表达式就好比一个模板
有且只有三剑客才能读懂这个模板,都是读一行处理一行
grep
文本过滤器(根据文本内容过滤文件),过滤来自一个文件或标准输入匹配模式内容
语法格式
grep [参数] [匹配规则] [操作对象]
参数
参数 | 描述 |
---|---|
-n | 过滤文本并将过滤后的内容显示出来 |
-A | 匹配成功后,将匹配行的后n行显示出来 |
-B | 匹配成功后,将匹配行的前n行显示出来 |
-C | 匹配成功后,将匹配行的前后n行都显示出来 |
-c | 只显示匹配成功的行数 |
-o | 只显示匹配成功的内容 |
-v | 反向过滤 |
-q | 静默输出 |
-i | 忽略大小写 |
-l | 匹配成功之后,将文本的名称打印出来 |
-E | 使用拓展正则,相当于egrep |
补充
静默输出下
$? : 上一行命令执行的结果,0代表执行成功,其他数字代表执行失败。
wc : 匹配行数
-l : 打印匹配行数
-c : 打印匹配的字节数
案例
案例1:在/etc/passwd文件中,匹配以ftp开头的行
[root@localhost tmp]# grep '^ftp' /etc/passwd
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
案例2:案例2:在/etc/passwd文件中,匹配以bash结尾的行
[root@localhost tmp]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
案例3:匹配本机中有哪些ip
[root@localhost tmp]# ip a | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'
127.0.0.1
192.168.15.100
192.168.15.255
172.16.1.100
172.16.15.255
| 表示先执行管道符后面的
o 只显示匹配成功的
E 使用扩展正则
案例4:要求将/etc/fstab中的去掉包含 # 开头的行,且要求 # 后至少有一个空格
[root@localhost tmp]# grep -vE '^#\ +' /etc/fstab
v 反向过滤
E 扩展正则
\ 转义
案例5:找出文件中至少有一个空格的行
[root@localhost tmp]# grep -E '\ +' xxx
案例6:案例6:将 nginx.conf 文件中以#开头的行和空行,全部删除
[root@localhost tmp]# grep -vE '^\ *#|^$' /etc/nginx/nginx.conf
sed
流媒体编辑器,过滤和替换文本
语法格式
sed [参数] 处理规则 [操作对象]
参数
参数 | 描述 |
---|---|
-e | 允许多项编辑 |
-n | 取消默认输出 |
-i | 就地编辑 |
-r | 支持扩展正则 |
-f | 指定sed匹配规则的脚本文件 |
- 就地编辑
就是将操作之后的结果执行
- 扩展正则
- 指定sed规则
Linux中如果一个命令里面的扩展内容非常多,为了防止写错,则可以
把扩展正则里面的内容用vim命令创建一个脚本文件。执行的时候加上
-f参数即可
编辑模式
- 删除(d)
删除第一行和第四行
[root@localhost /]# sed -e '1d' -e '4d' 1.txt
343255
43656547
35467
12145
- 打印(p)
默认输出打印出第四行
[root@localhost /]# sed -n '4p' 1.txt
12312
- 在当前行后添加一行内容(a)
- 修改当前行(c)
- 在当前行之前插入内容[单独使用时](i)
- 在指定行中读内容(r)
- 将指定行写入文件(w)
- 字符转换成另一个字符(y)
- 字符串转换成另一个字符串
- 全部执行(g)
g模式配合s模式把s模式替换之后的命令在本行全部执行
- 忽略大小写(i)
与s模式一起使用时可以忽略大小写
- 代表前面匹配到的内容(&)
定位
- 数字定位法
指定行号
sed '2d' 1.txt 指定删除第二行
sed '2,d' 1.txt 指定删除第二行到第三行
- 正则定位法
指定正则定位
sed '/^f/d' 1.txt 指定删除以f开头的行
双斜杠'//'内写正则表达式
- 数字正则定位法
数字正则定位
sed '4,/^f/d' 1.txt 指定删除第四行到以f开头的行
双斜杠'//'内写正则表达式
- 正则正则定位法
正则正则定位
sed '/^f/,/^g/' 1.txt 指定删除从以f开头的行到以g开头的行
双斜杠'//'内写正则表达式
案例
案例1:
将yum.conf中的注释行全部去掉
[root@localhost etc]# sed '/^ *#/d' /etc/yum.conf
案例2:
将yum.conf中的每一行增加注释
[root@localhost etc]# sed 's/.*/# &/g' /etc/yum.conf
案例3:
一键修改本机ip
192.168.15.100 ---> 192.168.15.101
172.16.1.100 ---> 172.16.1.101
sed -i 's#.100#.101#g' /etc/sysconfig/network-scripts/ifcfg-eth[01]
案例4:
将/etc/passwd中的root修改成ROOT
sed -i 's#root#ROOT#g' /etc/passwd
awk
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。
之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
语法格式
awk [参数] [处理规则] [操作对象]
参数
-F 指定文本分隔符(默认是以空格作为分隔符)
案例
打印系统所有用户的解析器
[root@localhost ~]# awk -F: '{print $NF}' /etc/passwd
awk的生命周期
grep、sed和awk都是读一行处理一行,直至处理完成。
1、接收一行作为输入
2、把刚刚读入进来得到文本进行分解
3、使用处理规则处理文本
4、输入一行,赋值给$0,直至处理完成
5、把处理完成之后的所有的数据交给END{}来再次处理
awk中的预定义变量
$0 : 代表当前行
[root@localhost ~]# awk -F: '{print $0, "---"}' /etc/passwd
$n :代表第n列
[root@localhost ~]# awk -F: '{print $1}' /etc/passwd
NF :记录当前行的字段数
[root@localhost ~]# awk -F: '{print NF}' /etc/passwd
[root@localhost ~]# awk -F: '{print $NF}' /etc/passwd
NR :用来记录行号
[root@localhost ~]# awk -F: '{print NR}' /etc/passwd
FS :指定文本内容分隔符(默认是空格)
[root@localhost ~]# awk 'BEGIN{FS=":"}{print $NF, $1}' /etc/passwd
FS与NR效果一样 优先级要高于 -F
OFS :指定打印分隔符(默认空格)
[root@localhost ~]# awk -F: 'BEGIN{OFS=" >>> "}{print $NF, $1}' /etc/passwd
awk处理规则的执行流程
BEGIN{}
BEGIN中的内容是在awk开始扫描输入之前执行,一般用来初始化或设置全局变量
END{}
END之后的操作将在扫描完全部的输入之后执行
//
正则表达式
{}
循环
awk中的函数
print : 打印
printf :格式化打印
%s : 字符串
%d :数字
- :左对齐
+ :右对齐
15 : 至少占用15字符
[root@localhost ~]# awk -F: 'BEGIN{OFS=" | "}{printf "|%+15s|%-15s|\n", $NF,$1}' /etc/passwd
格式化打印第一列和最后一列用 | 分隔,前后各占15个字符
awk中的定位
1.正则表达式
[root@localhost ~]# awk -F: '/root/{print $0}' /etc/passwd
[root@localhost ~]# awk -F: '/^root/{print $0}' /etc/passwd
2.比较表达式(文本内内容)
>
<
>=
<=
~ 正则匹配
!~ 正则匹配(取反)
案例:要求打印属组ID大于属主ID的行
[root@localhost ~]# awk -F: '$4 > $3{print $0}' /etc/passwd
案例:结尾包含bash
[root@localhost ~]# awk -F: '$NF ~ /bash/{print $0}' /etc/passwd
案例:结尾不包含bash
[root@localhost ~]# awk -F: '$NF !~ /bash/{print $0}' /etc/passwd
- 3.逻辑表达式
&& : 逻辑与
|| :逻辑或
! :逻辑非
[root@localhost ~]# awk -F: '$3 + $4 > 2000 && $3 * $4 > 2000{print $0}' /etc/passwd
属组和属主相加大于2000且属组和属主相乘大于2000
[root@localhost ~]# awk -F: '$3 + $4 > 2000 || $3 * $4 > 2000{print $0}' /etc/passwd
属组和属主相加大于2000或属组和属主相乘大于2000
[root@localhost ~]# awk -F: '!($3 + $4 > 2000){print $0}' /etc/passwd
属组和属主相加不大于2000
- 4.算术表达式
+
-
*
/
%
案例1:要求属组 + 属主的ID 大于 2000
[root@localhost ~]# awk -F: '$3 + $4 > 2000{print $0}' /etc/passwd
案例2:要求属组 * 属主的ID 大于 2000
[root@localhost ~]# awk -F: '$3 * $4 > 2000{print $0}' /etc/passwd
案例3:要求打印偶数行
[root@localhost ~]# awk -F: 'NR % 2 == 0{print $0}' /etc/passwd
案例4:要求打印奇数行
[root@localhost ~]# awk -F: 'NR % 2 == 1{print $0}' /etc/passwd
- 5.条件表达式
==
>
<
>=
<=
案例:要求打印第三行
[root@localhost ~]# awk -F: 'NR == 3{print $0}' /etc/passwd
- 6.范围表达式
[root@localhost ~]# awk -F: '/^root/,/^ftp/{print $0}' /etc/passwd
以root开始的行到以ftp开头的行
- 7.流程控制
只存在循环之中。
if
[root@localhost ~]# awk -F: '{if($3>$4){print "大于"}else{print "小于或等于"}}' /etc/passwd
if(){}
if(){}else{}
if(){}else if(){}else{}
for
[root@localhost ~]# awk -F: '{for(i=10;i>0;i--){print $0}}' /etc/passwd
for(i="初始值";条件判断;游标){}
while
[root@localhost ~]# awk -F: '{i=1; while(i<10){print $0, i++}}' /etc/passwd
while(条件判断){}
每隔5行,打印一行横线
-------------------------------------------------------------------------
[root@localhost ~]# awk -F: '{if(NR%5==0){print "----------------"}print $0}' /etc/passwd