正则表达式
使用单个字符串来描述或者匹配一系列符合某个句法规则的字符串,在很多文本编辑器或者其他工具里,正则通常用来检索和替换那些符合某个模式的文本内容。
grep/egrep 工具的使用
-c 表示打印符合要求的行数
-i 表示忽略大小写
-n 表示输出符合要求的行及行号
-v 表示打印不符合要求的行 取反
-A 后面跟一个数字(有无空格都行) 例如-A2表示打印符合要求的行以及下面两行
-B 后面跟一个数字(有无空格都行) 例如-B2表示打印符合要求的行以及上面两行
-C 后面跟一个数字(有无空格都行) 例如-A2表示打印符合要求的行以及上下各两行
-A
[root[[@localhost](https://my.oschina.net/u/570656)]# grep -A1 'root' passwd.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
--
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
[root[[@localhost](https://my.oschina.net/u/570656)]#
-B
[root[[@localhost](https://my.oschina.net/u/570656)]# grep -B1 'root' passwd.txt
root:x:0:0:root:/root:/bin/bash
--
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root[[@localhost](https://my.oschina.net/u/570656)]#
-C
[root[[@localhost](https://my.oschina.net/u/570656)]# grep -C1 'root' passwd.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
--
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
[root@localhost ~]#
-c
[root@localhost ~]# grep -c 'root' passwd.txt
2
[root@localhost ~]#
-n
[root@localhost ~]# grep -n 'root' passwd.txt
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]#
-i
[root@localhost ~]# grep -i 'root' passwd.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
RooTx:48:48:Apache:/usr/share/httpd:/sbin/nologin
[root@localhost ~]#
-v
[root@localhost ~]# grep -v 'nologin' passwd.txt
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
[root@localhost ~]#
过滤出所有带数字的行
[root@localhost ~]# grep '[0-9]' passwd.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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
过滤出所有不带数字的行
[root@localhost ~]# grep -v '[0-9]' passwd.txt
RooTx:::Apache:/usr/share/httpd:/sbin/nologin
[root@localhost ~]#
过滤出所有空行和以#开头的行
[root@localhost ~]# cat !$
cat test.txt
#qwe
qwe
##
[root@localhost ~]# grep -v '^$' test.txt | grep -v '^#'
qwe
[root@localhost ~]#
^ 代表行首 $代表行尾 空行则用^$ 表示
过滤出任意一个字符或者重复字符
[root@localhost ~]# grep 'r.o' passwd.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]#
*.表示任意一个字符 表示零个或者多个字符
[root@localhost ~]# grep '.*' passwd.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
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
表示匹配所有
指定要过滤出的字符出现字数
[root@localhost ~]# egrep 'o{2}' passwd.txt
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
RooTx:::Apache:/usr/share/httpd:/sbin/nologin
**符号{},内部为数字,表示前面得字符要重复的次数,这里使用 egrep命令,可以不需要转义字符,如果使用grep则需要加上转义符 \ 。 **
{}也可以表达一个范围,{n1,n2},其中n1<n2,表示重复n1到n2次前面得字符,n2可以为空,这时表示大于或等于n1次。
过滤出一个或多个指定的字符
[root@localhost ~]# egrep 'oo+' passwd.txt
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
[root@localhost ~]# egrep 'ooo+' passwd.txt
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
[root@localhost ~]#
符号+ ,表示匹配1个或者多个+前面得字符, 这个 + 不支持被 grep直接使用的。
过滤出零个或者一个指定的字符
[root@localhost ~]# egrep 'ooo?' passwd.txt
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
[root@localhost ~]#
过滤出任何可匹配条件的内容
[root@localhost ~]# egrep 'aaa|111|ooo|Roo' passwd.txt
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
aaaa
11111
[root@localhost ~]#
()演示
[root@localhost ~]# egrep 'r(oo|oooos)h' passwd.txt
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
rooh
[root@localhost ~]#
()表示一个整体,会把包含rooh或者roooosh的行匹配出来
Sed工具
-n表示只显示我们要打印的行
-p 表示打印
[root@localhost ~]# sed -n '/root/'p passwd.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]#
下面则是不加 -n的。所有内容都显示了
[root@localhost ~]# sed '/root/'p passwd.txt
root:x:0:0:root:/root:/bin/bash
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
rooh
aaaa
11111
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost ~]#
打印指定开头的行
[root@localhost ~]# sed -n '/^1/'p passwd.txt
11111
[root@localhost ~]#
打印指定结尾的行
[root@localhost ~]# sed -n '/sh$/'p passwd.txt
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
-e 实现多个行为
[root@localhost ~]# sed -n -e '1'p -e '/111/'p passwd.txt
root:x:0:0:root:/root:/bin/bash
11111
[root@localhost ~]#
'1' 表示打印第一行
删除某些行
**-d表示删除**
[root@localhost ~]# sed '1'd passwd.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
删除了第一行
[root@localhost ~]# sed '1,3'd passwd.txt
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/nolo
删除了1-3行
但是你查看这个文档时,会发现内容并未有减少。可见,这个操作仅仅是在显示屏幕上并不显示这些行而已,文档内容并不会减少
[root@localhost ~]# cat passwd.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
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/no
替换字符或者字符串
**-s 表示替换**
[root@localhost ~]# sed 's/rooh/bbbb/g' passwd.txt
root:x:0:0:root:/root:/bin/bash
bbbb
aaaa
11111
[root@localhost ~]#
-g 表示全局替换,不加则是替换本行出现的第一个 rooh字符
除了使用 / 作为分隔符外,还可以使用其他特殊字符,如 # @ $ 等
[root@localhost ~]# sed 's$bbbb$cccc$g' passwd.txt
root:x:0:0:root:/root:/bin/bash
rooh
cccc
11111
[root@localhost ~]#
[root@localhost ~]# sed 's@aaaa@dddd@g' passwd.txt
root:x:0:0:root:/root:/bin/bash
rooh
dddd
11111
[root@localhost ~]#
删除文档中的所有数字或者字母
由于我替换后的内容为空,所以就是删除
[root@localhost ~]# sed 's/[0-9]//g' passwd.txt
root:x:::root:/root:/bin/bash
bin:x:::bin:/bin:/sbin/nologin
daemon:x:::daemon:/sbin:/sbin/nologin
adm:x:::adm:/var/adm:/sbin/nologin
[root@localhost ~]# sed 's/[a-zA-Z]//g' passwd.txt
::0:0::/://
::1:1::/://
::2:2::/://
::3:4:://://
::4:7::///://
::5:0::/://
调换2个字符串的位置
[root@localhost ~]# sed -r 's/(root)(.*)(bash)/\3\2\1/' passwd.txt
bash:x:0:0:root:/root:/bin/root
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
root对应1 bash对应3 中间的所有字符对应2
调换顺序为 bash在前,root在后。
由于小括号是特殊符号,则需要使用转义 \ 才可以正常使用,否则需要加上 -r 参数
直接修改文件内容
**-i 修改文件内容**
[root@localhost ~]# sed -i 's/bash/abc/' passwd.txt
[root@localhost ~]# head -n1 passwd.txt
root:x:0:0:root:/root:/bin/abc
[root@localhost ~]#
由于是直接修改文件内容。建议修改前,请备份文件。以免改错。
awk工具
截取文档中的某个段
[root@localhost ~]# head -n2 passwd.txt | awk -F ':' '{print $1}'
root
bin
[root@localhost ~]#
-F指定分隔符,如果不加分隔符,则以空格或者tab为分隔符
print则是打印的动作,$1表示第一个字段,$2为第二个字段。以此类推。 $0比较特殊,表示整行
print里还可以自定义内容。但需要以双引号括起来。演示如下
[root@localhost ~]# head -n2 passwd.txt | awk -F ':' '{print $1 $2 "qq" $4}'
rootxqq0
binxqq1
[root@localhost ~]#
匹配字符或者字符串
[root@localhost ~]# awk '/ooo/' passwd.txt
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
[root@localhost ~]#
指定某个段去匹配内容
~ 表示匹配
[root@localhost ~]# awk -F ':' '$5~/ooo/' passwd.txt
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
[root@localhost ~]#
多次匹配
[root@localhost ~]# awk -F ':' '/Roo/ {print $1,$3} /root/ {print $1,$3}' passwd.txt
root 0
operator 11
RooTx
[root@localhost ~]#
匹配完 Roo 在匹配root
条件操作符
[root@localhost ~]# awk -F ':' '$3>500' passwd.txt
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost ~]#
awk可以使用逻辑符号判断,== < > 等等一些符号
在和数字比较时,把数字加上双引号,那么awk则会认为这个是字符,不加双引号,则会认为是数字
[root@localhost ~]# awk -F ':' '$7!="/sbin/nologin"' passwd.txt
root:x:0:0:root:/root:/bin/abc
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
RooTx:::Apache:/usr/rooooshare/httpd:/sbin/nologin
rooh
aaaa
11111
[root@localhost ~]#
2个字段之间比较
[root@localhost ~]# awk -F ':' '$3>$4 ' passwd.txt
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
operator:x:11:0:operator:/root:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost ~]#
**&& 演示 **
[root@localhost ~]# awk -F ':' '$3>5 && $3<7 ' passwd.txt
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
[root@localhost ~]#
|| 演示
[root@localhost ~]# awk -F ':' '$3>998 || $7=="/sbin/shutdown"' passwd.txt
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
[root@localhost ~]#
awk内置变量
常用变量有 OFS 、NF和NR
OFS 用来定义分隔符,但仅是在输出时定义。
NF 用来表示用分隔符分割后一共有多少段
NR 表示行号
OFS演示
[root@localhost ~]# head -n5 passwd.txt | awk -F ':' '{OFS="@"} {print$1,$2,$3}'
root@x@0
bin@x@1
daemon@x@2
adm@x@3
lp@x@4
[root@localhost ~]#
awk条件使用if语句
[root@localhost ~]# awk -F ':' '{OFS="%"} {if ($3>997) {print$1,$2}}' passwd.txt
polkitd%x
chrony%x
[root@localhost ~]#
NF演示
[root@localhost ~]# head -n5 passwd.txt | awk -F ':' '{print NF}'
7
7
7
7
7
[root@localhost ~]#
NR演示
[root@localhost ~]# awk 'NR>20' passwd.txt
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
rooh
aaaa
11111
nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@localhost ~]#
[root@localhost ~]# cat passwd.txt | wc -l
25
[root@localhost ~]#
也可配合段使用
[root@localhost ~]# awk -F ':' 'NR <20 && $1 ~ /root/' passwd.txt
root:x:0:0:root:/root:/bin/abc
[root@localhost ~]#
awk 中数学运算
[root@localhost ~]# head -n3 passwd.txt | awk -F ':' '$1="root"'
root x 0 0 root /root /bin/abc
root x 1 1 bin /bin /sbin/nologin
root x 2 2 daemon /sbin /sbin/nologin
[root@localhost ~]#
[root@localhost ~]# head -n3 passwd.txt | awk -F ':' '{$7=$3+$4} {print $0}'
root x 0 0 root /root 0
bin x 1 1 bin /bin 2
daemon x 2 2 daemon /sbin 4
[root@localhost ~]#
END语法
END是awk特有语法,表示所有行都已执行
[root@localhost ~]# head -n5 passwd.txt | awk -F ':' '{(tot=tot+$3)}; END {print tot}'
10
[root@localhost ~]# head -n5 passwd.txt
root:x:0:0:root:/root:/bin/abc
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
[root@localhost ~]#
if判断
[root@localhost ~]# awk -F ':' '{if ($1=="root") {print $0}}' passwd.txt
root:x:0:0:root:/root:/bin/abc
[root@localhost ~]#
以上仅是awk,sed grep/egrep的简单使用。
正则习题练习:http://www.apelearn.com/study_v2/chapter14.html