一、正则表达式
1.正则表达式的概念
REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。
正则表达式被很多程序和开发语言所广泛支持:vim, less,grep,sed,awk, nginx,mysql 等
1.1正则表达式与通配符的区别
正则表达式主要用来匹配字符串(命令结果,文本内容)
通配符匹配文件(而且是已存在的文件)
-
基本正则表达式
-
扩展正则表达式
1.2 元字符(字符匹配)
. 匹配任意单个字符,可以是一个汉字
[] 匹配指定范围内的任意单个字符,示例:[zhou] [0-9] [] [a-zA-Z] [[:alpha:]] [0-9a-zA-Z]= [:alnum:]
[^] 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z]
[:alnum:] 字母和数字`
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母`
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符 (水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
\w #匹配单词构成部分,等价于[_[:alnum:]]
\W #匹配非单词构成部分,等价于[^_[:alnum:]]
\S #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\s #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意Unicode 正则表达式会匹配全角空格符`
1.3表示次数
*#匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* #任意长度的任意字符 不包括0次
\? #匹配其前面的字符出现0次或1次,即:可有可无
\+ #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
\{n\} #匹配前面的字符n次
\{m,n\} #匹配前面的字符至少m次,至多n次
\{,n\} #匹配前面的字符至多n次,<=n
\{n,\} #匹配前面的字符至少n次
ifconfig ens33|grep netmask|grep -o
#举例
过滤ip地址
[root@xkj ~]# ifconfig ens33|grep netmask|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'|head -n1
192.168.100.254
1.4 位置锚定
^ #行首锚定, 用于模式的最左侧 $ #行尾锚定,用于模式的最右侧 ^PATTERN$ #用于模式匹配整行 (单独一行 只有root) ^$ #空行 ^[[:space:]]*$ # 空白行 tab 换行 回车 \< 或 \b #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部) \> 或 \b #词尾锚定,用于单词模式的右侧 \<PATTERN\> #匹配整个单词
思考过滤出不是已#号开头的非空行 [root@localhost ~]#grep "^[^#]" /etc/fstab [root@localhost data]#grep "^google$" test.txt #只匹配google 这个字符 [root@localhost ~]#grep "^[[:space:]]*$" /etc/fstab [root@localhost ~]#echo hello-123 |grep "\<123" #除了 字母 数字 下划线其他都算 单词的分隔符 hello-123 [root@localhost ~]#echo hello 123 |grep "\<123" hello 123
1.5 分组或其他
分组:( ) 将多个字符捆绑在一起,当作一个整体处理,如:(root)+
后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名
方式为: \1, \2, \3, ... 分组
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例
[root@localhost ~]#echo abccc |grep "abc\{3\}"
abccc
[root@localhost ~]#echo abcabcabc |grep "\(abc\)\{3\}"
#分组 匹配abc
abcabcabc
[root@localhost ~]#echo 1abc |grep "1\|2abc"
#只匹配了1
1abc
[root@localhost ~]#echo 1abc |grep "\(1\|2\)abc"
#1abc或者2abc
1abc
[root@localhost ~]#ifconfig ens33|grep netmask|grep -o '\([0-9]\{1,3\}\.\)\{3\}[0-9]\{3\}'|head -1
192.168.91.100
[root@localhost ~] ens33 |grep netmask|grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'|head -1
[root@localhost ky15]#ifconfig ens33 |grep netmask|grep -Eo '([0-9]{1,3}.){4}'
1.6 扩展正则表达式(表示字符相差不大)
grep -E
egrep 默认使用的 是扩张正则
表示次数
* 匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
{,n} #匹配前面的字符至多n次,<=n,n可以为0
{n,} #匹配前面的字符至少n次,<=n,n可以为0
表示分组
() 分组 分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+ 后向引用:\1, \2, ... | 或者 a|b #a或b C|cat #C或cat (C|c)at #Cat或cat
二、文本命令
1.grep命令
1.1基本格式
grep [选项]… 查找条件 目标文件
1.2常用选项
| 选项 | 功能 |
|---|---|
| -m[x] | 匹配x次后停止,x为具体数字 |
| -v | 取反 |
| -i | 忽略字符大小写 |
| -n | 显示匹配的行号 |
| -c | 统计匹配的行数 |
| -o | 仅显示匹配到的字符串 |
| -q | 静默模式,不输出任何信息 |
| -e | 实现多个选项间的逻辑or关系 |
| -w | 匹配整个单词 |
| -E | 使用扩展正则表达式,相当于egrep |
| -F | 不支持正则表达式,相当于fgrep |
| -r | 递归目录,但不处理软连接 |
| -R | 递归目录,但处理软连接 |
| -f | 处理两个文件相同内容,把第一个文件作为匹配条件 |
| -A x | 匹配内容的后x行 |
| -B x | 前x行 |
| -C x | 前后各x行 |
[root@xkj ~]# grep -m 1 root /etc/passwd #只匹配一次 root:x:0:0:root:/root:/bin/bash [root@xkj ~]# grep -m 5 root /etc/passwd #匹配多次 匹配多次root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin [root@xkj ~]# grep -Ev '^[[:space:]]*#|^$' /etc/fstab /dev/mapper/centos-root / xfs defaults 0 0 UUID=6a6b9aa4-d7dd-4a07-a45e-a59fd506806d /boot xfs defaults 0 0 /dev/mapper/centos-home /home xfs defaults 0 0 /dev/mapper/centos-swap swap swap defaults 0 0 #使用拓展正则表达式匹配不以空格和#开头的行 [root@xkj ~]# grep -A3 root /etc/passwd #匹配含root的行和后三行 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin -- operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin [root@xkj ~]# grep -e root -e bash /etc/passwd #匹配包含root或者bash的行 root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin xkj:x:1000:1000:xkj:/home/xkj:/bin/bash [root@xkj ~]# grep -c root /etc/passwd #统计包含root的行数 2
2.sed命令
1.1sed核心功能
sed的核心功能:增删改查(可配合正则表达式) 查: p 删: d 改: s(字符串替换)、c(整行替换)、y(对应字符进行替换,效果类似tr命令) 增: i(在行前插入内容)、a(在行后添加内容)、r(在行后读入文件的内容) 复制粘贴:H(复制)、d(删除)、G(粘贴到指定行下方)
1.2 命令格式
sed [option]... 'script;script;...' [input file...]选项 自身脚本语法 支持标准输入管道
1.3常用选项
| 选项 | 功能 |
|---|---|
| -n | 不输出模式空间内容到屏幕(不自动打印) |
| -e | 类似grep的-e,可实现多脚本运行 |
| -f | 从指定文件中读取编辑脚本 |
| -r或者-E | 使用拓展正则表达式 |
| -i.bak | 备份文件并原处编辑 |
| -s | 将多个文件视为独立文件,而不是单个连续的长文件流 |
[root@xkj ~]# sed -n -e '/^r/p' -e'/^b/p' /etc/passwd #把passwd文件中r为首和b为首的内容打印出来 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin radvd:x:75:75:radvd user:/:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
1.4 sed脚本语法
1.4.1 基本语法结构
[address]<command>[options]匹配范围 命令 选项 address 表示要匹配的行范围,可以是单个行号、行号范围或正则表达式。 command 表示要在匹配的行上执行的命令。 options 是一些可选的参数,用于修改命令的行为。
1.4.2 地址部分(指定匹配范围)
在 sed 脚本中,地址部分用于指定要匹配的行范围。 地址部分可以是单个行号、行号范围或正则表达式。
1)不指定范围
地址部分是可选的,如果不指定地址,Sed 将对所有行都执行命令
2)单个行号
#基本格式# sed 'n<command>' file #处理第n行的内容,n为具体正整数 #举个例子# sed '2d' file #删除文件中的第 2 行。
3)行号范围
#基本格式# sed 'x,y<command>' file #处理x行到y行的内容,x和y为正整数且x<y sed 'x,+y<command>' file #处理x行和x行后y行的内容 #举个例子# sed '2,5d' file #删除文件中第2行到第5行的内容 sed '2,+5d' file #删除文件中第2行到第7行的内容
4)使用正则表达式匹配范围
#基本格式# sed '/pattern/<command>' file #根据正则表达式来匹配目标行 sed '/pattern1/,/pattern2/<command>' file #匹配正则表达式1和正则表达式2间的行,并根据command进行处理 sed 'x,/pattern/<command>' file #x行到正则表达式匹配到的行之间的内容 sed '/pattern/,y<command>' file #正则表达式匹配到的行到y行之间的内容
[root@xkj ~]# sed -n '/^root/,/^daemon/p' /etc/passwd #打印出root开头到daemon开头的行 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin
5)步进
'~' 符号 #怎么表示奇数行? sed -n '1~2p' #从第一行开始,步进为2打印,即1 3 5 7。。。 sed '0~2d' #怎么表示偶数行? sed -n '2~2p' #从第二行开始,步进为2打印,即2 4 6 8。。。 sed '1~2d'
6)最后一行和倒序匹配
`$` 符号用于表示最后一行 sed -n '$<command>' file #对最后一行进行操作 sed -n '$,$-n<command>' file #倒数第n行到最后一行
1.4.3命令部分(要执行的命令)
| 命令 | 功能 |
|---|---|
| p | 将匹配到的行打印输出 |
| lp | 忽略大小写输出 |
| d | 删除模式空间匹配的行,并立即启用下一轮循环 |
| a\ | 将指定的文本添加到匹配到的行后面 |
| i\ | 将指定的文本插入到匹配到的行前面 |
| c\ | 替换行为单行或多行文本 |
| w 文件 | 保存模式匹配的行至指定文件 |
| r 文件 | 读取指定文件的文本至模式空间中匹配到的行后 |
| = | 为模式空间中的行打印行号 |
| ! | 模式空间中匹配行取反处理 |
| q | 结束或退出sed |
#用sed打印到第三行 sed -n '1,3p' 文件 sed '3q' 文件 #q是自动退出,打印到第三行就退出 #打印从第三行开始,继续往后打印三行 sed -n '3,+3p'
特殊字符和转义序列 &: 表示与模式匹配的整个文本。 \1, \2, ...: 表示与模式中括号内的子表达式匹配的文本。 \n: 表示换行符。 \t: 表示制表符。 \\: 表示反斜杠。
1.5 sed查找替换
1.5.1 基本语法
sed 's/要查找的内容/替换的内容/修饰符' 文件名 # '/'为分隔符,可以用'@' 或者 '#' # 要查找的内容可以用正则表达式 # 替换的内容无法用正则表达式 # 修饰符 # g 行内全局替换 p 显示替换成功的行 w /PATH/FILE 将替换成功的行保存至文件中 I,i 忽略大小写
sed -i 's/r..t/&er/g' /etc/passwd # &代指前面找到的内容
1.5.2 sed分组和后向引用
1.分组
通过将模式的一部分放入一个分组中,可以将这部分模式视为一个单元,后续可以通过引用该分组在替换中使用。
2.后向引用
在替换中使用前面定义的分组的内容。在sed命令中,可以使用 \数字的形式引用分组,其中数字表示分组的顺序。
在替换中使用\1来引用第一个分组的内容。如果有多个分组,可以使用\2、\3等来引用后续分组的内容。
#举个例子 echo 123abcxyz | sed -nr 's/(123)(abc)(xyz)/\1/p' # -n 关闭自动打印 -r 使用扩展正则表达式 # 123分成1组 abc分组第二组 xyz分成第三组 # \1/p 表示打印第一组 [root@xkj ~]# echo 123abcxyz | sed -nr 's/(123)(abc)(xyz)/\1/p' 123 示例1 仅显示本机ip地址 [root@xkj ~]# ifconfig ens33 | sed -nr 's/.*inet (.*) netmask.*/\1/p' 192.168.100.254 示例2 仅显示tmp文件的权限 [root@xkj ~]# stat /tmp文件:"/tmp"大小:8192 块:24 IO 块:4096 目录 设备:fd00h/64768d Inode:67148168 硬链接:83 权限:(1777/drwxrwxrwt) Uid:( 0/ root) Gid:( 0/ root) 环境:system_u:object_r:tmp_t:s0 最近访问:2016-11-05 23:38:36.000000000 +0800 最近更改:2024-05-15 16:06:11.881576249 +0800 最近改动:2024-05-15 16:06:11.881576249 +0800 创建时间:- [root@xkj /]# stat tmp | sed -nr '4s/.*\(([0-9]+)\/.*/\1/p' 1777
1.5.3 变量调用
name=root #定义变量 sed -nr '/'$name'/p' /etc/passwd #打印出包含root的内容 或者 sed -nr /"$name"/p /etc/passwd
[root@xkj /]# name=root [root@xkj /]# sed -nr '/'$name'/p' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
3.awk命令
3.1awk工作原理
读取输入:AWK首先读取输入文件或从标准输入接收输入;
分割输入:AWK默认将输入行分割成字段,并使用空格或制表符作为字段分隔符;
匹配模式:AWK使用模式匹配来确定需要处理的行,可以使用正则表达式或其他条件来指定匹配的行。如果没有指定模式,AWK将默认匹配所有行;
执行动作:当输入行与模式匹配时,AWK执行相应的动作;
处理下一行:一旦完成当前行的处理,AWK继续处理下一行,重复上述步骤。
3.2awk命令格式
#命令格式#
awk [选项] '[模式匹配条件]{处理动作 }' 文件1 文件2..
3.2.1常用选项
#选项#
#一般只有-F常用
-F 指定分隔符,默认的分隔符是若干个连续空白符,默认的时候可不写
-v 自定义变量
-f 脚本
awk '/匹配条件/{ print $x }'
#匹配条件可以不写 x为任意数字
3.2.2 模式匹配条件
#模式匹配条件格式#/ 匹配条件 / # 起始 结束 #/ / 一定要加
3.2.3 处理动作
#操作#
#常用的 只有 print
awk '{ print $1 }'
awk '{ print $1 $2 $3 .... }'
#awk会自动压缩空格,不需要再写tr -s ' '
3.3awk常用内置变量
| 内置变量 | 功能 |
|---|---|
| FS | 指定每行文本的字段分隔符,缺省为空格或制表符(tab)。与 “-F”作用相同 -v “FS=:” |
| OFS | 在输出中字段之间的分隔符,默认为空格 |
| ORS | 在输出中记录之间的分隔符,默认为换行符 |
| NF | 字段数量,表示当前记录中的字段数 |
| NR | 记录编号,表示当前正在处理的输入记录的行号 |
| RS | 表示用于分割记录的字符,默认为换行符 |
| $0 | 当前处理的行的整行内容 |
| $n | 当前处理行的第n个字段(第n列) |
| FILENAME | 当前正在处理的文件的名称 |
3.4 BEGIN和END
BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;
awk再处理指定的文本,之后再执行END模式中指定的动作;
END{ } 语句块中,往往会放入打印结果等语句
awk 'BEGIN {x=0};/\/bin\/bash$/;{x++};END{print x}' /etc/passwd
{x=0} # 在开始之前,初始化变量x为0
/\/bin\/bash$/ # 使用正则表达式匹配包含"/bin/bash"的行
{x++} # 每匹配到一行,变量x加1
END {print x} # 结束后,输出变量x的值
[root@xkj /]# awk 'BEGIN {x=0};/\/bin\/bash$/;{x++};END{print x}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
xkj:x:1000:1000:xkj:/home/xkj:/bin/bash
44
3.5 NR
示例1 打印特定行号行的内容
[root@xkj /]# awk 'NR==3' /etc/passwd
daemon:x:2:2:daemon:/sbin:/sbin/nologin
#打印第三行的内容
示例2 计算输入文件的总行数
[root@xkj /]# awk 'END {print NR}' /etc/passwd
44
示例3 奇偶数行
NR%2==1取奇数行
NR%2==0取偶数行
awk 'NR%2==1 {print $2}' 文件名 #奇数行提取
awk 'NR%2==0 {print $2}' 文件名 #偶数行提取
[root@xkj /]# awk 'NR%2==1 {print $1}' test.txt
1
3
5
7
9
[root@xkj /]# awk 'NR%2==0 {print $1}' test.txt
2
4
6
8
10
示例4 多行处理
[root@xkj /]# awk '{if (NR%2 == 0) {print "aaa: " $0} else {print "bbb: " $0}}' test.txt
bbb: 1
aaa: 2
bbb: 3
aaa: 4
bbb: 5
aaa: 6
bbb: 7
aaa: 8
bbb: 9
aaa: 10
3.6 NF
示例1 打印每一行的字段数量
[root@xkj /]# awk '{print NF}' test.txt
2
2
1
1
2
1
2
1
1
1
示例2 打印每一行的最后一个字段
[root@xkj /]# awk '{print $NF}' test.txt
1
2
3
4
2
6
2
8
9
10
示例3 根据字段数量执行不同的操作
[root@xkj /]# awk '{if (NF < 2) {print "小: " $0} else {print "大: " $0}}' test.txt
大: 1 1
大: 2 2
小: 3
小: 4
大: 5 2
小: 6
大: 7 2
小: 8
小: 9
小: 10
#字段数小于2的行前面加小 其他加大
3.7 awk实例
统计/etc/fstab文件中每个文件系统类型出现的次数
[root@xkj /]# cat /etc/fstab |awk '/^[^#]/{print}'|awk '{print $3}'|sort |uniq -c1 swap3 xfs