转眼一周的学习过程又告一段落了,从前面的基础内容到现在真正的关键时候正则表达式,学习从现在开始应该是到了一个真正决定以后工作高度的时候。
首先我们还是回顾一下上次课程内容:
Shell基础 这里主要是几个命令需要了解一下:sort cut uniq tr split
1.正则表达式
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
2.1grep 的基本用法:
grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]
下面这几个是主要参数一定要记住的,其余的可以随时用随时查。
-c 只输出匹配行的计数。
-i 不区分大小写(只适用于单字符)。
-h 查询多文件时不显示文件名。
-l 查询多文件时只输出包含匹配字符的文件名。
-n 显示匹配行及行号。
-s 不显示不存在或无匹配文本的错误信息。
-v 显示不包含匹配文本的所有行。
2.2 grep的实例(这里我就找了一些实例题目来看一下具体用法和老师的有点不一样)
扩展内容:需要过滤出自已的IP地址
[root@localhost ~]# ip addr
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:ec:fc:cf brd ff:ff:ff:ff:ff:ff
inet 192.168.139.168/24 brd 192.168.139.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:feec:fccf/64 scope link tentative dadfailed
valid_lft forever preferred_lft forever
这里我们可以看到我们的是inet 192.168.139.168/24
[root@localhost ~]# ip addr |grep -B1 'ens33'|awk '/inet/{print $2}'
192.168.139.168/24
第1列:城市位置编号。
第2列:月份。
第3列:存储代码及出库年份。
第4列:产品代号。
第5列:产品统一标价。
第6列:标识号。
第7列:合格数量。
file.txt文件内容:
48 Dec 3BC1977 LPSX 68.00 LVX2A 138
483 Sept 5AP1996 USP 65.00 LVX2C 189
47 Oct 3ZL1998 LPSX 43.00 KVM9D 512
219 dec 2CC1999 CAD 23.00 PLV2C 68
484 nov 7PL1996 CAD 49.00 PLV2C 234
483 may 5PA1998 USP 37.00 KVM9D 644
216 sept 3ZL1998 USP 86.00 KVM9E 234
\>表示后面为空
使用g r e p抽取精确匹配的一种更有效方式是在抽取字符串后加\ >
1.含有“48”字符串的行的总数 //过滤出所选单词统计行数
[root@localhost ~]# grep -n '48' 2.txt |wc –l
4
2显示含有“48”字符串的所有行的行号
[root@localhost ~]# grep -n '48' 2.txt
1:48 dec 3BC1977 LPSX 68.00 LVX2A 138
2:483 Sept 5AP1996 USP 65.00 LVX2C 189
5:484 nov 7PL1996 CAD 49.00 PLV2C 234
6:483 may 5PA1998 USP 37.00 KVM9D 64
3.精确匹配只含有“48”字符串的行 //"\>"这里将>转义一下表示结束符
[root@localhost ~]# grep -n '48\>' 2.txt
1:48 dec 3BC1977 LPSX 68.00 LVX2A 138
4. 抽取代码为4 8 4和4 8 3的城市位置
[root@localhost ~]# grep '48[3|4]' 2.txt
483 Sept 5AP1996 USP 65.00 LVX2C 189
484 nov 7PL1996 CAD 49.00 PLV2C 234
483 may 5PA1998 USP 37.00 KVM9D 644
5. 显示使行首不是4或8
[root@localhost ~]# egrep -nv '^[4|8]' 2.txt
4:219 dec 2CC1999 CAD 23.00 PLV2C 68
7:216 sept 3ZL1998 USP 86.00 KVM9E 234
6.显示含有九月份的行
[root@localhost ~]# grep -n 'sept' 2.txt
7:216 sept 3ZL1998 USP 86.00 KVM9E 234
7.显示以K开头,以D结尾的所有代码
[root@localhost ~]# grep -e 'K.*D\>' 2.txt
47 Oct 3ZL1998 LPSX 43.00 KVM9D 512
483 may 5PA1998 USP 37.00 KVM9D 644
8.显示头两个是大写字母,中间两个任意,并以C结尾的代码
[root@localhost ~]# grep -e '[A-Z][A-Z]..C\>' 2.txt
483 Sept 5AP1996 USP 65.00 LVX2C 189
219 dec 2CC1999 CAD 23.00 PLV2C 68
484 nov 7PL1996 CAD 49.00 PLV2C 234
9.查询所有以5开始以1 9 9 6或1 9 9 8结尾的所有记录
[root@localhost ~]# grep -e '5.*199[6|8]\>' 2.txt
483 Sept 5AP1996 USP 65.00 LVX2C 189
483 may 5PA1998 USP 37.00 KVM9D 644
3.1 sed比起grep有者更为强大的功能,它还可以查找替换。sed是一种流编辑器,它是文本处理中非常有用的工具,能够完美的配合正则表达式使用
3.2 sed的基本用法:
文件:指定待处理的文本文件列表
d |
删除,删除选择的行 |
D |
删除模板块的第一行 |
s |
替换指定字符 |
h |
拷贝模板块的内容到内存中的缓冲区 |
H |
追加模板块的内容到内存中的缓冲区 |
g |
获得内存缓冲区的内容,并替代当前模板块中文本 |
G |
获得内存缓冲区的内容,并追加到当前模板块文本的后面 |
l |
列表不能打印字符的清单 |
n |
读取下一个输入行,用下一个命令处理新的行而不是第一个命令 |
N |
追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码 |
p |
打印模板块的行 |
P |
打印模板块的第一行 |
q |
退出sed |
b label |
分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾 |
r file |
从file中读行 |
t label |
if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾 |
T label |
错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾 |
w file |
写并追加模板块到file末尾 |
W file |
写并追加模板块的第一行到file末尾 |
! |
表示后面的命令对所有没有被选定的行发生作用 |
= |
打印当前行号 |
# |
把注释扩展到第一个换行符以前 |
sed替换标记
命令 |
说明 |
g |
表示行内全面替换 |
p |
表示打印行 |
w |
表示把行写入一个文件 |
x |
表示互换模板块中的文本和缓冲区中的文本 |
y |
表示把一个字符翻译为另外的字符(但是不用于正则表达式) |
\1 |
子串匹配标记 |
& |
已匹配字符串标记 |
sed元字符集
命令 |
说明 |
^ |
匹配行开始,如:/^sed/匹配所有以sed开头的行。 |
$ |
匹配行结束,如:/sed$/匹配所有以sed结尾的行。 |
. |
匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。 |
* |
匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。 |
[] |
匹配一个指定范围内的字符,如/[sS]ed/匹配sed和Sed。 |
[^] |
匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。 |
(..) |
匹配子串,保存匹配的字符,如s/(love)able/\1rs,loveable被替换成lovers。 |
& |
保存搜索字符用来替换其他字符,如s/love/&/,love这成love。 |
< |
匹配单词的开始,如:/ |
> |
匹配单词的结束,如/love>/匹配包含以love结尾的单词的行。 |
x{m} |
重复字符x,m次,如:/0{5}/匹配包含5个0的行。 |
x{m,} |
重复字符x,至少m次,如:/0{5,}/匹配至少有5个0的行。 |
x{m,n} |
重复字符x,至少m次,不多于n次,如:/0{5,10}/匹配5~10个0的行。 |
3.3 sed的实例(这里我就把阿铭老师书里面的题目拿出来做一下非常有代表性)
1.把/etc/passwd 复制到/root/test.txt,用sed打印所有行
[root@localhost ~]#cp /etc/passwd 1.txt
[root@localhost ~]# sed -n ''p 1.txt
oot: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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/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
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
#$%%%%
324242
2.打印test.txt的3到10行
[root@localhost ~]# sed -n '3,10'p 1.txt
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
3. 打印test.txt 中包含 ‘root’ 的行
[root@localhost ~]# sed -n '/root/'p 1.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
4. 删除test.txt 的15行以及以后所有行
[root@localhost ~]# sed '15,$'d 1.txt
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
hutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/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
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
5. 删除test.txt中包含 ‘bash’ 的行
[root@localhost ~]# sed '/bash/'d 1.txt
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/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
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
6. 替换test.txt 中 ‘root’ 为 ‘toor’
[root@localhost ~]# sed 's/root/toor/g' 1.txt
oot:x:0:0:toor:/toor:/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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/toor:/sbin/nologin
7. 替换test.txt中 ‘/sbin/nologin’ 为 ‘/bin/login’
[root@localhost ~]# sed 's@/sbin/nologin@bin/login@g' 1.txt
oot:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:bin/login
daemon:x:2:2:daemon:/sbin:bin/login
adm:x:3:4:adm:/var/adm:bin/login
lp:x:4:7:lp:/var/spool/lpd:bin/login
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:bin/login
operator:x:11:0:operator:/root:bin/login
games:x:12:100:games:/usr/games:bin/login
ftp:x:14:50:FTP User:/var/ftp:bin/login
nobody:x:99:99:Nobody:/:bin/login
systemd-network:x:192:192:systemd Network Management:/:bin/login
dbus:x:81:81:System message bus:/:bin/login
polkitd:x:999:998:User for polkitd:/:bin/login
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:bin/login
postfix:x:89:89::/var/spool/postfix:bin/login
chrony:x:998:996::/var/lib/chrony:bin/login
8. 删除test.txt中5到10行中所有的数字
[root@localhost ~]# sed '5,10s/[0-9]//g' 1.txt
lp:x:::lp:/var/spool/lpd:/sbin/nologin
sync:x:::sync:/sbin:/bin/sync
shutdown:x:::shutdown:/sbin:/sbin/shutdown
halt:x:::halt:/sbin:/sbin/halt
mail:x:::mail:/var/spool/mail:/sbin/nologin
operator:x:::operator:/root:/sbin/nologin
9.删除test.txt 中所有特殊字符(除了数字以及大小写字母)//在原先的基础字段上面我加了一行特殊字符的行
[root@localhost ~]# sed -r 's/[^0-9a-zA-Z]//g' test.txt
rootx00rootrootbinbash
binx11binbinsbinnologin
daemonx22daemonsbinsbinnologin
admx34admvaradmsbinnologin
lpx47lpvarspoollpdsbinnologin
syncx50syncsbinbinsync
user1x10011001homeuser1binbash
[root@localhost ~]# cat test.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
user1:x:1001:1001::/home/user1:/bin/bash
#%^^&$$$$$$$
10..把test.txt中第一个单词和最后一个单词调换位置 //这个就比较复杂了,可能需要慢慢消化一下
sed -r 's/([a-zA-Z]+)(.*)(\/[a-zA-Z]+)/\3\2\1/' test.txt
[root@localhost ~]# sed 's/\(^[a-zA-Z][a-zA-Z]*\)\([^a-zA-Z].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)/\4\2\3\1/' test.txt
bash:x:0:0:root:/root:/bin/root
nologin:x:1:1:bin:/bin:/sbin/bin
nologin:x:2:2:daemon:/sbin:/sbin/daemon
nologin:x:3:4:adm:/var/adm:/sbin/adm
nologin:x:4:7:lp:/var/spool/lpd:/sbin/lp
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
nologin:x:8:12:mail:/var/spool/mail:/sbin/mail
nologin:x:11:0:operator:/root:/sbin/operator
nologin:x:12:100:games:/usr/games:/sbin/games
nologin:x:14:50:FTP User:/var/ftp:/sbin/ftp
nologin:x:99:99:Nobody:/:/sbin/nobody
nologin-network:x:192:192:systemd Network Management:/:/sbin/systemd
nologin:x:81:81:System message bus:/:/sbin/dbus
nologin:x:999:998:User for polkitd:/:/sbin/polkitd
nologin:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/sshd
nologin:x:89:89::/var/spool/postfix:/sbin/postfix
nologin:x:998:996::/var/lib/chrony:/sbin/chrony
bash:x:1000:1000::/home/knightlai:/bin/knightlai
bash1:x:1001:1001::/home/user1:/bin/user
11.把test.txt中出现的第一个数字和最后一个单词替换位置 //这个就比较复杂了,可能需要慢慢消化一下
[root@localhost ~]# sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*\)\([^a-zA-Z]\)\([a-zA-Z][a-zA-Z]*$\)#\1\5\3\4\2#' test.txt
root:x:bash:0:root:/root:/bin/0
bin:x:nologin:1:bin:/bin:/sbin/1
daemon:x:nologin:2:daemon:/sbin:/sbin/2
adm:x:nologin:4:adm:/var/adm:/sbin/3
lp:x:nologin:7:lp:/var/spool/lpd:/sbin/4
sync:x:sync:0:sync:/sbin:/bin/5
shutdown:x:shutdown:0:shutdown:/sbin:/sbin/6
halt:x:halt:0:halt:/sbin:/sbin/7
mail:x:nologin:12:mail:/var/spool/mail:/sbin/8
operator:x:nologin:0:operator:/root:/sbin/11
games:x:nologin:100:games:/usr/games:/sbin/12
ftp:x:nologin:50:FTP User:/var/ftp:/sbin/14
nobody:x:nologin:99:Nobody:/:/sbin/99
systemd-network:x:nologin:192:systemd Network Management:/:/sbin/192
dbus:x:nologin:81:System message bus:/:/sbin/81
polkitd:x:nologin:998:User for polkitd:/:/sbin/999
sshd:x:nologin:74:Privilege-separated SSH:/var/empty/sshd:/sbin/74
postfix:x:nologin:89::/var/spool/postfix:/sbin/89
chrony:x:nologin:996::/var/lib/chrony:/sbin/998
knightlai:x:bash:1000::/home/knightlai:/bin/1000
userbash:x:1001:1001::/home/user1:/bin/1
#%^^&$$$$$$$
12.把test.txt 中第一个数字移动到行末尾
[root@localhost ~]# sed 's#\([^0-9][^0-9]*\)\([0-9][0-9]*\)\([^0-9].*$\)#\1\3\2#' test.txt
root:x::0:root:/root:/bin/bash0
bin:x::1:bin:/bin:/sbin/nologin1
daemon:x::2:daemon:/sbin:/sbin/nologin2
adm:x::4:adm:/var/adm:/sbin/nologin3
lp:x::7:lp:/var/spool/lpd:/sbin/nologin4
sync:x::0:sync:/sbin:/bin/sync5
shutdown:x::0:shutdown:/sbin:/sbin/shutdown6
halt:x::0:halt:/sbin:/sbin/halt7
mail:x::12:mail:/var/spool/mail:/sbin/nologin8
operator:x::0:operator:/root:/sbin/nologin11
games:x::100:games:/usr/games:/sbin/nologin12
ftp:x::50:FTP User:/var/ftp:/sbin/nologin14
nobody:x::99:Nobody:/:/sbin/nologin99
systemd-network:x::192:systemd Network Management:/:/sbin/nologin192
dbus:x::81:System message bus:/:/sbin/nologin81
polkitd:x::998:User for polkitd:/:/sbin/nologin999
sshd:x::74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin74
postfix:x::89::/var/spool/postfix:/sbin/nologin89
chrony:x::996::/var/lib/chrony:/sbin/nologin998
knightlai:x::1000::/home/knightlai:/bin/bash1000
user:x:1001:1001::/home/user1:/bin/bash1
13.在test.txt 20行到末行最前面加 ‘aaa:’
[root@localhost ~]# sed '20s/^.*/aaa&/' test.txt
aaaknightlai:x:1000:1000::/home/knightlai:/bin/bash