正则
含义:就是一串有规律的字符串
掌握好正则对于编写shell脚本有很大帮助
各种编程语言中都有正则,原理是一样的
本章将要学习grep/egrep、sed、awk
grep
用来过滤指定关键词的
创建一个实验环境,创建mkdir grep;进入cd grep;拷贝cp /etc/passwd grep
格式:grep后边跟关键词在跟文件名
-c 显示行数
-n 显示行号
-v 取反,意思就是把你指的关键词之外的全显示出来,例如我一开始指定要带nologin的,加上-v之后就会显示不带有它的,如图。
-r 把一些子目录或者孙目录所有下边的文件遍历一遍
-A后面跟数字,过滤出符合要求的行以及下面的n行,意思就是比如你要过滤关键词root,加上-A2,它会给你把只要有root关键词的这一行加上往下的两行一起列出来,如下图。
-B跟A相反,过滤出符合要求的行以及上面的n行
-C全是AB的结合,过滤出符合要求的行以及上下各n行
grep ‘[0-9]’ 表示过滤0-9的数字,例如,grep ’[0-9]’ passwd 如下图
grep -n ‘^#’ ^以什么开头的,意思是以#号开头的行
grep -vn ‘^#’ 意思是不以#号开头的行
grep ‘[^0-9]’ 把里边非0-9的列出来
grep ‘^[^0-9]’ 当^放到[]里面时,他就是取反的意思,以一个非数字开头的行全部列出来
grep -v ‘^[^0-9]’相反的行
grep ‘r.o’ .表示任意的一个字符,不管是a-z,A-Z,0-9,还是特殊符号都能匹配到
grep ‘o*o’ *表示0个过多个*前面的字符,0次也算,跟+号相似+号是1次或多次
grep ‘.*’ 表示任意一个任意字符,都匹配
单独匹配一行
grep ‘o\{2\}’ 一样的命令还有egrep ‘o{2}’ grep -E ‘o{2}’花括号表示前面这个字符的重复范围
egrep -n ‘(oo){2}’ passwd
egrep ‘o+o’或grep ‘o\+o’ passwd +意思是一个或多个加号前边的字符,0次不算。跟*号相似,*是0次或者多次。
egrep ‘o?t’ ?表示零个或一个问号前边的字符,要么有一次要么就没有,有就是ot没有就是t
grep -E ‘root|nologin’ passwd 竖线是或者的意思,只要有root的或则nologin的都会匹配,
或者用egrep ‘root|nologin’ passwd
sed
匹配指定的字符
sed -n 只匹配一个指定字符例如,sed -n ‘/root/’p test.txt 只匹配有root字符的行
sed -r 加上r之后就不用拖意了,例如,sed -nr ‘/o+t/’p test.txt
[root@aaa-01 sed]# sed -nr '/o+t/'p test.txt
root:x:0:0:root:/root:/bin/bash
operatoooooor:x:11:0:operator:/root:/sbin/nologin
sed -nr ‘/o{2}/’p test.txt匹配两次o
[root@aaa-01 sed]# sed -nr '/o{2}/'p test.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
operatoooooor:x:11:0:operator:/root:/sbin/nologin
或者:sed -nr ‘/root|bus/’p test.txt
[root@aaa-01 sed]# sed -nr '/root|bus/'p test.txt
root:x:0:0:root:/root:/bin/bash
operatoooooor:x:11:0:operator:/root:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
指定打印的行p
sed -n ‘5’p test.txt 打印指定的行
[root@aaa-01 sed]# sed -n '5'p test.txt
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sed -n ‘1,5’p test.txt 打印指定范围的行
[root@aaa-01 sed]# sed -n '1,5'p 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
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sed -n ’20,$’p test.txt 打印指定的行到末尾的行,$末尾行的意思1,&是全部打印出来
[root@aaa-01 sed]# sed -n '20,$'p test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1010:1008::/home/user6:/bin/bash
打印指定的字符:例如只打印root的行,sed -n ‘/root/’p test.txt
[root@aaa-01 sed]# sed -n '/root/'p test.txt
root:x:0:0:root:/root:/bin/bash
operatoooooor:x:11:0:operator:/root:/sbin/nologin
以一个字符开头的,例如以p开头的行,sed -n ‘/^p/’p test.txt
[root@aaa-01 sed]# sed -n '/^p/'p test.txt
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sed -n ‘in$’p test.txt
sed -n ‘/r..o/’p test.txt
sed -n ‘oo*’p test.txt
sed -e ‘1’p -e ‘/111/’p -n test.txt
sed -e 在同一个表达式里边做多项操作,例如,我不仅要把第一行打印出来还要匹配字符串awei,sed -e ‘1’p -e ‘/awei/’p -n test.txt
特性:sed -e ‘1’p -e ‘/root/’p -n test.txt
在p后边加上大I就不会区分大小写了sed -e ‘1’p -e ‘/bus/’Ip -n test.txt
d删除指定的行
sed ‘1,20’d test.txt 意思是把一到二十行删除,但是他并没有删除,只是把剩下的行给列出来
[root@aaa-01 sed]# sed '1,20'd test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
user5:x:1007:1007::/home/user5:/bin/bash
user6:x:1010:1008::/home/user6:/bin/bash
[root@aaa-01 sed]# wc -l test.txt
26 test.txt
set -i 这个是删除选项,例如删除指定行sed -i ‘1,6’d test.txt
[root@aaa-01 sed]# sed -i '1,6'd test.txt
[root@aaa-01 sed]# wc -l test.txt
20 test.txt
删除指定字符的行 例如:sed -i ‘/user5/’d test.txt
[root@aaa-01 sed]# sed -i '/user5/'d test.txt
[root@aaa-01 sed]# tail -n4 test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
user6:x:1010:1008::/home/user6:/bin/bash
s替换指定的字符
例如:
sed '1,10s/root/toor/g' test.txt 意思是把一到十行里的root替换成toor 如下图
删除英文字母:sed ‘s/[a-zA-Z]//g’如下图,head test.txt | sed ‘s/[a-zA-Z]//g’
出现两个//时它会报错我们需要加上\,例如:sed ‘s//root/123/g’换成sed ‘s/\/root/123/g’ 如下图:
在所有的行前面加上一个固定的字符串如下图:sed -r ‘s/(.*)/aaa:&/’ test.txt
如何把第一段和最后一段调换位置,如下图:
sed '/^\s*$/d' passwd 去除空行 sed 's/^[ \t]*//g' passwd 去除首行空格 sed 's/^[ ]*//g' passwd sed '/^[ ].*/'d passwd
awk
把第一段打印出来:awk -F ‘:’ ‘{print $1}’ test.txt 如下图:
打印所有的段用0表示:awk ‘{print $0}’ test.txt 不加-F选项他默认字符中的空格或者空白部分为分隔符
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
打印指定更多的段:awk -F ‘:’ ‘{print $1,$2,$3,$4}’ test.txt
[root@aaa-01 awk]# awk -F ':' '{print $1,$2,$3,$4}' test.txt
root x 0 0
bin x 1 1
daemon x 2 2
adm x 3 4
lp x 4 7
打印指定更多的段并且用特殊符号给他分割:awk -F ‘:’ ‘{print $1″#”$2″#”$3″#”$4}’ test.txt
[root@aaa-01 awk]# awk -F ':' '{print $1"#"$2"#"$3"#"$4}' test.txt
root#x#0#0
bin#x#1#1
daemon#x#2#2
adm#x#3#4
lp#x#4#7
列出指定的字符的段,例如oo:awk ‘/oo/’ test.txt
只要第一段带oo的:awk -F ‘:’ ‘$1 ~/oo/’ test.txt
多个表达式一起写:awk -F ‘:’ ‘/root/ {print $1,$3} /test/ {print $1,$3}’ /etc/passwd
查找第三段等于0行:awk -F ‘:’ ‘$3==”0″‘ test.txt
[root@aaa-01 awk]# awk -F ':' '$3=="0"' test.txt
root:x:0:0:root:/root:/bin/bash
或者查找第三段等于零的行,并且只要第一段:
[root@aaa-01 awk]# awk -F ':' '$3=="0" {print $1}' test.txt
root
查找指定的段大于等于1000的:awk -F ‘:’ ‘$3>=1000’ test.txt
[root@aaa-01 awk]# awk -F ':' '$3>=1000' test.txt
awei:x:1000:1000::/home/awei:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1004:1003::/home/user3:/bin/bash
user4:x:1006:1003::/home/awei111:/sbin/nologin
查找某一段大于等于500的:awk -F ‘:’ ‘$3>=”500″‘ test.txt
!=意思就是不等于:awk -F ‘:’ ‘$7!=”/sbin/nologin”‘ test.txt
[root@aaa-01 awk]# awk -F ':' '$7!="/sbin/nologin"' test.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
awei:x:1000:1000::/home/awei:/bin/bash
还可以把第几段小于第几段的列出来:awk -F ‘:’ ‘$3<$4’ test.txt
相等的段也可以列出来:awk -F ‘:’ ‘$3==$4’ test.txt
&&并且 还可以把一段大于几并且小于几的一同列出来,;如第三段大于2并且小于6的列出来:awk -F ‘:’ ‘$3>”2″ && $3<“6″‘ test.txt
||或者:awk -F ‘:’ ‘$3>1000 || $7==”/bin/bash”‘ test.txt
awk -F ‘:’ ‘$3>1000 || $7 ~ “/sin/”‘ test.txt
OFS是在你打印的时候指定的分隔符。例如:awk -F ‘:’ ‘{OFS=”#”} {if ($3>1000) {print $1,$2,$3,$4}}’ test.txt
NR表示打印时的行:awk -F ‘:’ ‘{print NR”: “$0}’ test.txt 显示行号的意思,把所有的行打印出来。
NF表示打印是每一行有多少段:awk -F ‘:’ ‘{print NF”: “$0}’ test.txt
只要前十行:awk -F ‘:’ ‘NR<=10’ test.txt
[root@aaa-01 awk]# awk -F ':' 'NR<=10' 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
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
计算某个段落的总和:awk -F ‘:’ ‘{(tot=tot+$3)}; END {print tot}’ /etc/passwd END表示所有的行都已经执行。
转载于:https://blog.51cto.com/12922638/2123556
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/101630.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...