正则表达式(regular expression,RE
)是一种 字符模式,用于在查找过程中匹配指定的字符。
在大多数程序中,正则表达式都被放在 两个正斜杠 之间;
例如:/I[oO]ve/
就是正斜杠界定的正则表达式–> 表示匹配love
和lOve
在正则表达式中,元字符是最重要的概念
1.Linux 正则表达式grep,sed,awk
;
2.大量字符串文件需要进行配置,而且是非交互式的;
3.过滤相关的字符串,匹配字符串,打印字符串。
注意事项
alias grep='grep --color=auto
^root 行首定位符 查找以root开头的行
bash$ 行尾定位符 查找以bash结尾的行
. 匹配单个字符 代表任意一个字符
0* 匹配前导符0到多次 匹配ro*t的o,可以有0个o,也可以有多个o
.* 任意多个字符 不管什么数字字符都匹配上
[o0] 匹配指定范围内一个字符 o和0都匹配上
[0-9] 匹配指定范围内一个字符 是数字全匹配上
[^0-9] 匹配不在指定范围内的 除了不匹配数字,其他全匹配
\ 转义元字符 love\. 将点转义,否则点代表任意字符,不显示
\ 词尾定位符 root\> 定位以root结尾的单词
\(..\) 匹配稍后使用的字符的标签
-------------------
x\{m\} 字符x重复出现m次 o\{3\} o重复出现3次
x\{m,\} 字符x重复出现m次,以上 o\{3,\} o重复出现3次以上
x\{m,n\} 字符x重复出现m到n次 o\{5,10\) o重复出现5到10次
2.1 grep家族
grep:在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行
egrep:扩展的egrep,支持更多的正则表达式元字符
fgrep:固定grep fixed grep,字面解释所有的字符 (看到什么就是什么)
2.2 grep命令
grep [选项] '模式 filename1 filename2
返回值:
找到: grep返回状态码0
没找到: grep返回状态码1
找不到文件: grep返回状态码2
grep选项
-i,--ignore-case
忽略大小写
-n,--line-number
匹配每一行前加上相对行号
-c,--count
显示成功匹配的行数
-q,--quiet,--silent
匹配上也不回显,多用于shell脚本
-v,--invert-match
取反,只显示不匹配的行
-o,--only-matching
只显示匹配的内容
-w
, 只匹配单个单词
2.3 grep实例
匹配以ro
开头的行:
# grep '^ro' /etc/passwd
匹配以ot
结尾的行:
# grep 'ot$' /etc/passwd
排除空行:
#grep -v '^$' /etc/nsswitch.conf
同时匹配两次^ :#grep "^[^rc]oot" /etc/passwd
- 第一个^ :表示匹配以什么开头
- 第二个^:表示排除r或c开头的词
匹配所有字符[a-zA-Z0-9]:
# grep '\w' /etc/passwd
所有字母与数字之外非字符:
# grep '\W' /etc/passwd
词边界
# grep '\broot\b' /etc/passwd
\b=\< 或 \>
2.4 egrep实例
查找包含NW 或EA 的行
#egrep ’NW|EA‘ datafile
查找有一到多个3的行
#egrep ’3+‘ datafile
查找2+0到多个点+一个数字
#egrep ’2\.?[0-9]‘ datafile
查找一个或多个no
#egrep ’(no)+' datafile
查找Sh 或Su的行
#egrep ‘S(h|u)' datafile
查找Sh或u 的行
#egrep ’Sh|u‘ datafile
取出ip add中的IP
最方便的方式:
# hostname -I
192.168.31.153
方式一:
# ip add | grep inet | egrep -o "[0-9]{3}.[0-9]{1,}.[0-9]{1,}.[0-9]{1,}"
127.0.0.1
192.168.31.153
192.168.31.255
方式二:
# ip add | grep inet | egrep -o "[0-9]{3}.[0-9]+.[0-9]+.[0-9]+"
127.0.0.1
192.168.31.153
192.168.31.255
sed是一个流编辑器,非交互式的编辑器,一次处理一行。
处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)。
接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行
3.1 sed命令
#sed [选项] ‘模式’ filename1 filename2
sed支持对指定行进行操作,包括打印,删除,修改,追加
选项 功能
-e 允许多项编辑
-n 取消默认的输出
-i 直接修改对应内容
-r 支持扩展元字符(不需要再对符号转义)
返回值
sed和grep不一样
不管是否找到:返回值都是0
语法错误时:返回值才是非0
3.2 支持正则表达式
与grep一样,sed在文件中查找模式时也可以使用正则表达式
正则表达式是 括在斜杠间的模式,用于查找和替换,以下是sed支持的元字符
使用基本元字符集^ $ . * [] [^] \< \> (\) {\}
使用扩展元字符集? + { } | ()
使用扩展元字符的方式:
使用斜线转义\+ sed -r
3.2 sed实例
//打印命令p
相当于cat命令
#sed ' ' filename
打印第二行
#sed -n '2p' filename
(-n:取消默认输入文件内容)
打印匹配到的行
# sed '/halt/p' passwd -n halt:x:7:0:halt:/sbin:/sbin/halt
打印最后一行
# sed -n '$p' passwd
//删除命令-d
删除第2行
# sed -rn '2d' passwd
#sed -r '{2d}' passwd
删除最后一行
# sed -r '$d' passwd
删除第3行到最后一行
# sed -r '3,$d' passwd
删除带有root的行(正则表达式)
# sed -r '/root/d' passwd
删除#号注释行
#sed -ri '/^[ \t]*#/d' file.conf
删除//号的注释行
# sed -ri '\#^[ \t]*//#d' test
# sed -r '/^[ \t]*\/\//d' test
删除空行
# sed -ri '/^[ \t]*$/d' test
删除注释行及空行
#sed -ri '/^[ \t]*#/d;/^[ \t]*$/d' test
#sed -r '/^[ \t]*($|#)/d' filename
//修改文件-c
#sed -ri ’/UserDNS/cUserDNS no/d‘ /etc/ssh/ssh_config
#sed -ri '$a\chroot_local=YES' /etc/vsftpd/vsftpd.conf
//在最后一行添加chroot_local=YES
#sed -ri '/^SELINUX=/cSELINUX=disabled/d' /etc/selinux/config
//查找SELINUX开头的行,整行替换成SELINUX=disabled
# sed -r '1,5s/^#*/#/' c.txt
//将1,5行的0个到多个#,换成一个#(避免出现有一个#,再加一个#不好看)·
//给文件添加注释
# sed -r 's/^/#/' resolve
# sed -r '1,4s/^/#/' resolve #给1-4行添加注释
# sed -r '2,6s/.*/#&99/' passwd 在第二行到第六行最前面添加#,& 行后,添加99
root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin99
#daemon:x:2:2:daemon:/sbin:/sbin/nologin99
#adm:x:3:4:adm:/var/adm:/sbin/nologin99
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin99
#sync:x:5:0:sync:/sbin:/bin/sync99
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
总结:
1. 打印p
2. 删除d
3. 追加a、i
4. 替换c
5. 替换sg
正则匹配替换
针对特定的行进行匹配
6. 非交互式修改文件
面试题:
假如有一个20G的文件,想编辑其中的一行。怎么办?
答:
使用sed,sed把当前处理的第一行存在模式空间中,查看是否是想编辑的该行,不是就接着处理下一行。(一行一行的读不会卡)
awk是一个强大的文本处理工具,通常配合脚本进行使用。
awk是一种编程语言,用于Linux下对文本和数据进行处理
语法:
#awk [选项] (参数)
选项:
-F 定义输入字段分隔符,默认分隔符为空格或tab键
-F “:” ==>定义以 :作为分隔字段
参数:
BEGIN{} {} END{}
行处理前 行处理中 行处理后
BEGIN{} 通常用于定义一些变量
FS:指定字段分隔符,跟-F 一样的效果
OFS:
理解行处理前/中/后:
# awk 'BEGIN{print 1/2} {print "ok"} END {print "Game Over"}' /etc/hosts
|行处理前 | 行处理中 |行处理后
|0.5
|ok
|ok
|Game Over
awk命令格式(实例介绍)
//awk 'pattern' filename ==>仅使用匹配,匹配文件
# awk -F: '/root/' /etc/passwd
//awk '{action}' filename ==>对文件进行动作处理
# awk -F: '{print $1}' /etc/passwd
//awk 'pattern {action}' filename ==>匹配+处理动作
# awk -F: '/root/{print$1,$3}' passwd
# awk 'BEGIN{FS=":"} /root/{print $1,$3}' passwd
//判断条件输出内容,判断已用大于1G,打印出挂载点下的可用容量
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/centos-root 18G 1.4G 17G 8% /
devtmpfs 479M 0 479M 0% /dev
# df -h | awk '/\/$/ {if ($3>1) print $4}'
17G
如下命令awk -F: '{print $1,$3}' passwd
工作原理
# awk -F: '{print $1,$3}' passwd
root 0
bin 1
daemon 2
adm 3
$0
,每一行也可称为一个记录,以换行符结束;$1
开始;$1
,$3
之间有个,
逗号,逗号映射成另一个内部连梁OFS默认是空格(,
=OFS=空格);$0
中,覆盖上一行内容。重新将字符串分隔成字段;//$0:awk变量$0读取当前行的内容
# awk -F: '{print $0}' passwd
//NR:控制输出的行数,打印前三行 (支持大于、小于、等于)
# awk 'NR<=3{print $0}' passwd
//FNR:记录输入文件的编号,不同文件不连续编号。
# awk '{print FNR,$0}' passwd /etc/hosts
//NF:打印保存行的最后一列的内容
# awk -F: '{print $1,$NF}' passwd
root /bin/bash
//FS:指定字段分隔符,默认空格
# awk -F 'NR==2{print $1,$2}' /etc/resolv.conf
///指定多个分隔符,以空格冒号tab作为字段分隔
# awk -F'[ :\t]' '{print $1,$3,$4}' passwd
//OFS:自定义输出字段分隔符,默认是空格,修改方式如下
# awk -F: '/root/{print $1,$2,$3}' passwd root x 0
operator x 11
# awk 'BEGIN{FS=":"; OFS="++"} /root/{print $1,$2}' passwd
root++x
operator++x
更多更好的原创文章,请访问官方网站: 点我就能跳转咯-》https://nothingzh.gitee.io
也可关注“哎呦运维”微信订阅号,随时接受文章推送。