正则表达式入门
正则表达式使用单个字符串来描述,匹配一系列符合某个语法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在Linux中,grep、sed、awk等文本处理工具都支持通过正则表达式进行模式匹配。
1、常规匹配
一串不包含特殊字符的正则表达式匹配自己,例如:
[root@localhost shell]# cat /etc/passwd | grep root
就会在/etc/passwd/中匹配所有包含root的行
2、常用特殊字符
1)特殊字符:^
^ 匹配一行的开头。例如:
[root@localhost shell]# cat /etc/passwd | grep ^a
匹配出所有以a开头的行
2)特殊字符:$
$ 匹配一行的结束。例如:
[root@localhost shell]# cat /etc/passwd | grep t$
匹配出所有以t结尾的行
^$ 匹配空格或空行
[root@localhost shell]# cat /etc/passwd | grep -n ^$ #-n显示行号
3)特殊字符:.
. 匹配一个除回车以外的任意字符。例如:
[root@localhost shell]# cat /etc/passwd | grep r..t
匹配以r开头,t结尾,中间包含两个字符的所有行
4)特殊字符:*
*不单独使用,他和前一个字符连用,表示匹配前一个字符0次或多次。例如
[root@localhost shell]# cat /etc/passwd | grep ro.t
匹配rt、rot、root、rooot、rooooot等所有行
.*匹配中间为任意的字符
例如:匹配以a开头,in结尾,中间任意字符的行
[root@localhost shell]# cat /etc/passwd | grep ^a.*in$
adm:x:3:4:adm:/var/adm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
5)特殊字符:\
\ 表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配某一特殊字符本身时(例如,我想找出所有包含‘$’的行),就会碰到困难。此时我们就要将转义字符和特殊字符连用,来表示特殊字符本身,例如:
[root@localhost shell]# cat /etc/passwd | grep ‘a\$b’
就会匹配所有包含a$b的行。注意需要使用单引号将表达式引起来。
6)字符区间(中括号):[ ]
[ ] 表示匹配某个范围内的一个字符,例:
[6,8]----匹配6或者8
[0-9]----匹配一个0到9的数字
[0-9]* ----匹配任意长度的数字字符串
[a-z]----匹配一个a到z之间的字符
[a-z]* ----匹配任意长度的字母字符串
[a-c,e-f]----匹配a-c或者e-f之间的任意字符
正则表达式扩展
定位符 | 说明 |
---|---|
^ | 锚定开头^a以a开头 默认锚定一个字符 |
$ | 锚定结尾a$ 以a结尾 默认锚定一个字符 |
匹配符 | 说明 |
---|---|
. | 匹配除回车以为的任意字符 |
( ) | 字符串分组 |
[ ^ ] | 表示否定括号中出现字符类中的字符,取反 |
\ | 转义字符 |
管道符 | 或 |
限定符 | 说明 |
---|---|
* | 某个字符之后加*表示该字符不出现或者出现多次 |
? | 与星号相似,但表示该字符出现一次或者不出现 |
+ | 表示其前面字符出现一次或者多次,但是必须出现一次 |
{n,m} | 某个字符之后出现,表示该字符最少n次,最多m次 |
{m} | 正好出现了m次 |
POSIX特殊字符 | 说明 |
---|---|
[:alnum:] | 匹配任意字母字符0-9 a-z A-Z |
[:alpha:] | 匹配任意字母,大写或者小写 |
[:digit:] | 数字0-9 |
[:graph:] | 非空字符(非空格控制字符) |
[:lower: ] | 小写字符a-z |
[:upper: ] | 大写字符A-Z |
[:cntrl:] | 控制字符 |
[:print:] | 非空字符(包括空格) |
[:punct:] | 标点符号 |
[:blank:] | 空格和TAB字符 |
[:xdigit:] | 16进制数字 |
[:space:] | 所有空白字符(新行、空格、制表符) |
文本处理工具
1、cut
cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的,cut命令从文件的每一句行剪切字节、字符和字段输出。
1)基本语法
cut [ 选项参数 ] filename
说明:默认分隔符是制表符
2)选项参数说明
选项参数 | 功能 |
---|---|
-f | 列号,提取第几列 |
-d | 分隔符,按照指定分隔符分割列,默认是制表符“\t” |
-c | 按字符进行切割,后加 n 表示取第几列,比如:-c 1 |
3)案例实操
(1)截取/etc/passwd/文件中过滤为bash的以“:”为分隔符的第1、6、7列
[root@localhost shell]# cat /etc/passwd | grep bash #grep可以相当于提取行
root:x:0:0:root:/root:/bin/bash
oracle:x:1000:1000:oracle:/home/oracle:/bin/bash
es:x:1001:1002::/home/es:/bin/bash
[root@localhost shell]# cat /etc/passwd | grep bash | cut -d ":" -f 1,6,7
root:/root:/bin/bash
oracle:/home/oracle:/bin/bash
es:/home/es:/bin/bash
(2)选取系统PATH变量值,截取第2个以“:”开始后的所有路径
[root@localhost shell]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/home/jdk1.8.0_291/bin:/root/bin
[root@localhost shell]# echo $PATH | cut -d ":" -f 2-
/usr/local/bin:/usr/sbin:/usr/bin:/home/jdk1.8.0_291/bin:/root/bin
2、awk
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分割符将每行切片,切开的部分再进行分析处理。
1)基本语法
awk [选项参数] ‘/pattern1/{action1} /patternl2/{action2}…’ filename
pattern:表示awk在数据中查找到的内容,就是匹配模式
action:在找到匹配内容时所执行的一系列命令
2)选项参数说明
选项参数 | 功能 |
---|---|
-F | 指定输入文件分隔符 |
-v | 赋值一个用户定义变量 |
3)案例实操
(1)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
[root@localhost shell]# cat /etc/passwd | grep ^root | cut -d ":" -f 7
/bin/bash
[root@localhost shell]# cat /etc/passwd | awk -F ":" '/^root/{print $7}'
/bin/bash
(2)搜索passwd文件以root关键字开头的所有行,并输出该行的第1,7列。
[root@localhost shell]# cat /etc/passwd | awk -F ":" '/^root/{print $1","$7}'
root,/bin/bash
(3)只显示/etc/passwd/的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell。在最后一行添加“end of file”。
[root@localhost shell]# cat /etc/passwd | awk -F ":" 'BEGIN{print "user,shell"} {print $1","$7} END{print "end of file"}'
user,shell
root,/bin/bash
bin,/sbin/nologin
……
lp,/sbin/nologin
sync,/bin/sync
shutdown,/sbin/shutdown
halt,/sbin/halt
mail,/sbin/nologin
operator,/sbin/nologin
……
tcpdump,/sbin/nologin
oracle,/bin/bash
mysql,/bin/false
es,/bin/bash
end of file
(4)将passwd文件中的用户ID增加1并输出
[root@localhost shell]# cat /etc/passwd | awk -v i=1 -F ":" '{print $3+i}'
1
2
3
4
……
4)awk的内置变量
变量 | 说明 |
---|---|
FILENAME | 文件名 |
NR | 已读的记录数(行号) |
NF | 浏览记录的域的个数(切割后,列的个数) |
5)案例实操
(1)统计passwd文件的文件名,每行的行号,每行的列数
[root@localhost shell]# awk -F ":" '{print "文件名:"FILENAME "行号:"NR "列数:"NF}' /etc/passwd
文件名:/etc/passwd行号:1列数:7
文件名:/etc/passwd行号:2列数:7
文件名:/etc/passwd行号:3列数:7
文件名:/etc/passwd行号:4列数:7
……
(2)查询ifconfig命令输出结果中的空格所在的行号
[root@localhost shell]# ifconfig | awk '/^$/{print NR}'
9
18
26
(3)切割IP
[root@localhost shell]# ifconfig ens33 | awk '/netmask/{print $2}'
192.168.105.85