基础正则表达式
正则表达式与通配符
- 正则表达式一般用来在文件中匹配符合条件的字符串,正则是包含匹配。grep、awk、sed命令都支持正则表达式
- 通配符用来匹配符合条件的文件名,通配符是完全匹配。ls find cp 这些命令不支持正则表达式,所以只能用shell通配符来匹配
基础正则表达式
元字符 | 作用 |
---|---|
* | 前一个字符匹配0次或者任意多次 |
. | 匹配除了换行符以外任意一个字符 |
^ | 匹配行首。例如:^hello会匹配以hello开头的行 |
$ | 匹配行尾。例如:hello$会匹配以hello结尾的行 |
[] | 匹配括号中的任意一个字符,之匹配一个字符。例如:[aeiou]匹配任意一个元音字母,[0-9]匹配任意一位数字,[a-z] [0-9]匹配小写字母和数字构成的两位字符 |
[^] | 匹配除中括号中的任意字符。例如:[^0-9] 匹配任意一位非数字字符,[^a-z] 表示匹配任意一位非小写字母 |
\ | 转义符。用于取消将特殊符号的含义取消 |
\{n\} | 表示前面的字符恰好出现n次。例如:[0-9]\{4\} 匹配四位数字,[1]{3-8}[0-9]\{9\} 匹配手机号码 |
\{n,\} | 表示前面的字符出现不小于n次。例如:[0-9]\{2,\} 表示两位及以上的数字 |
\{n,m\} | 表示前面的字符至少出现n次,最多出现m次。例如:[a-z]\{6,8\} 匹配6到8位小写字母 |
举例:
-
"*"
前面一个字符匹配一次或多次
grep “a*” test_rule.txt
#匹配所有内容包括空白行 -
grep “aa*” test_rule.txt
#匹配至少包含有一个a的行
-
grep “aaa*” test_rule.txt
#匹配至少包含两个连续a的字符串
-
grep “aaaaa*” test_rule.txt
匹配最少包含四个连续a的字符串
-
"."
匹配除了换行符以外任意一个字符grep “s…d” test_rule.txt
#"s…d"会匹配在s和d这两个字母之间一定有两个字符的单词
-
grep “s.*d” test_rule.txt
#匹配在s和d字母之前有任意字符
-
grep “.*” test_rule.txt
#匹配所有内容
-
grep “^a” test_rule.txt
#匹配以小写字母a开头的行
-
grep “j$” test_rule.txt
#匹配以小写字母j结尾的行
-
…
字符截取命令
cut
cut [选项] [文件名]
选项:
-f 列号: 提取低几列
-d 分隔符: 按照指定分隔符分割
注意:分隔符要用制表符tab键,要么是具体的符号
举例
[root@MiWiFi-R4CM-srv ~]# cat a.txt
ID Name gender Mark
1 aa m 90
2 bb f 98
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# cut -f 2 a.txt
Name
aa
bb
cc
[root@MiWiFi-R4CM-srv ~]# cut -d ":" -f 1,3 /etc/passwd
root:0
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
operator:11
games:12
ftp:14
nobody:99
systemd-network:192
dbus:81
polkitd:999
sshd:74
postfix:89
chrony:998
dockerroot:997
qilin:1000
user1:1001
user2:1002
yk:1003
tg:1004
#过滤除超级用户的所有用户(以后可以用作批量删除)
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd |grep /bin/bash|grep -v root|cut -d ":" -f 1
qilin
user1
user2
yk
tg
printf
printf ‘输出类型输出格式’ 输出内容
输出类型:
1. %ns:输出字符串。n是数字代表输出几个字符
2. %ni:输出整数。n是数字代表输出几个数字
3. %m.nf:输出浮点数。m和n都是数字,值代表输出的整数位数和小数位数,如%8.2f代表共输出8位数,其中2位是小数,6位是整数
输出格式:
1. \a :输出警告音
2. \b:输出退格键,也就是backspace键
3. \f:清除屏幕
4. \n:换行
5. \r:回车,也就是enter键
6. \t:水平输出退格键,也就是Tab键
7. \v:垂直输出退格键,也就是Tab键
举例:一个%s他为认为是一组
[root@MiWiFi-R4CM-srv ~]# printf %s 1 2 3 4 5 6
123456[root@MiWiFi-R4CM-srv ~]# printf %s%s%s 1 2 3 4 5 6
123456[root@MiWiFi-R4CM-srv ~]# printf %s %s %s 1 2 3 4 5 6
%s%s123456[root@MiWiFi-R4CM-srv ~]# printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6[root@MiWiFi-R4CM-srv ~]# printf '%s %s %s\n' 1 2 3 4 5 6
1 2 3
4 5 6
备注:printf 后面不能跟文件名也不能操作管道符对象
要想处理一个对象,需要使用系统命令来处理$()或``
[root@MiWiFi-R4CM-srv ~]# cat a.txt
ID Name gender Mark
1 aa m 90
2 bb f 98
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# printf %s a.txt
a.txt
[root@MiWiFi-R4CM-srv ~]# cat a.txt | printf '%s'
#采用调用系统命令的方式处理
[root@MiWiFi-R4CM-srv ~]# printf %s $(cat a.txt )
IDNamegenderMark1aam902bbf983ccm78[root@MiWiFi-R4CM-srv ~]#
[root@MiWiFi-R4CM-srv ~]# printf '%s\t %s\t %s\t %s\n' $(cat a.txt )
ID Name gender Mark
1 aa m 90
2 bb f 98
3 cc m 78
在awk命令的输出中支持print 和printf命令
- print:print会在每个输出之后自动加入一个换行符(linux 默认是没有print命令的)
- printf:printf是标准格式的输出命令,并不会自动加入换行符,如果需要换行,手动加入换行符
awk命令
awk ‘条件1{动作1}条件2{动作2}…’ 文件名
条件(Pattern):
一般使用关系表达式作为条件
x>10 判断变量x是否大于10
x>=10 大于等于
x<= 小于等于
动作(Action):
格式化输出
流程控制语句
举例:
[root@MiWiFi-R4CM-srv ~]# cat a.txt
ID Name gender Mark
1 aa m 90
2 bb f 98
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# awk '{printf $1 "\t" $2 "\n"}' a.txt
ID Name
1 aa
2 bb
3 cc
#查看分区占用情况
[root@MiWiFi-R4CM-srv ~]# df |awk '{print $1"\t"$5"\t"$6}'
文件系统 已用% 挂载点
devtmpfs 0% /dev
tmpfs 0% /dev/shm
tmpfs 2% /run
tmpfs 0% /sys/fs/cgroup
/dev/mapper/centos-root 90% /
/dev/sda1 17% /boot
/dev/sdb5 1% /disk5
/dev/sdb1 1% /disk1
.host:/ 71% /mnt/hgfs
tmpfs 0% /run/user/0
#查看根分区占用情况,根据拿到的值做报警处理
[root@MiWiFi-R4CM-srv ~]# df |grep /dev/mapper/centos-root |awk '{print $5}'|cut -f 1 -d"%"
90
BEGIN
[root@MiWiFi-R4CM-srv ~]# awk 'BEGIN{printf "text!!!\n"}{print $1 "\t" $4}' a.txt
text!!!
ID Mark
1 90
2 98
3 78
FS内置变量
FS定义分隔符:
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd|grep /bin/bash|awk 'BEGIN{FS=":"}{print $1 "\t" $3}'
root 0
qilin 1000
user1 1001
user2 1002
yk 1003
tg 1004
END
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd|grep /bin/bash|awk 'BEGIN{FS=":"}END{printf "aaaa"}{print $1 "\t" $3}'
root 0
qilin 1000
user1 1001
user2 1002
yk 1003
tg 1004
aaaa[root@MiWiFi-R4CM-srv ~]#
关系运算符
[root@MiWiFi-R4CM-srv ~]# cat a.txt
ID Name gender Mark
1 aa m 90
2 bb f 98
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# cat a.txt |grep -v ID|awk '$4>=90{printf $2"\n"}'
aa
bb
sed
sed是一中几乎包括在所有Unix平台(包括linux)的轻量级流编辑器,sed主要是用来将数据进行选取、替换、删除、新增的命令
sed [选项] ‘[动作]’ 文件名
选项:
-n :一般sed命令会把所有结果都输出到屏幕,如果加入此选项,则只会把经过sed命令处理的行输出到屏幕
-e: 允许对输入的数据应用多条sed命令编辑
-i :用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出
动作:
-
a:追加,在当前行后添加一行或多行,添加多行时,除最后一行外,每行末尾需要用‘\’代表数据未完结
-
c: 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需要用’'代表数据未完结
-
i: 插入,在当前行插入一行或多行,插入多行时,除最后一行外,每行末尾需要用‘\’代表数据未完结
-
d: 删除指定的行
-
p: 打印输出指定的行
-
s:字符串替换,用一个字符串替换另一个字符串。格式为“行范围s/旧字符串/新字符串/g”(和vim中的替换格式类似)
演示:
[root@MiWiFi-R4CM-srv ~]# cat a.txt
ID Name gender Mark
1 aa m 90
2 bb f 98
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# sed '2p' a.txt #不加n他会把你选定的行输出一次,同时还会把整个文件也输出一次
ID Name gender Mark
1 aa m 90
1 aa m 90
2 bb f 98
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# sed -n '2p' a.txt
1 aa m 90
[root@MiWiFi-R4CM-srv ~]# df -h |sed -n '2p' #也可以用作管道符操作
devtmpfs 475M 0 475M 0% /dev
[root@MiWiFi-R4CM-srv ~]# sed '2,3d' a.txt #删除第二和第三行,发现文件并没有被编辑;原因是没有加选项
ID Name gender Mark
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# sed -i '2,3d' a.txt
[root@MiWiFi-R4CM-srv ~]# cat a.txt
ID Name gender Mark
3 cc m 78
#在第二行后插入 注意:要真实替换文件里的内容需加-i
[root@MiWiFi-R4CM-srv ~]# sed '2a zuobi \
> tashizuobide' a.txt
ID Name gender Mark
3 cc m 78
zuobi
tashizuobide
#在第二行前插入 注意:要真实替换文件里的内容需加-i
[root@MiWiFi-R4CM-srv ~]# sed '2i zuobi \
tashizuobide' a.txt
ID Name gender Mark
zuobi
tashizuobide
3 cc m 78
[root@MiWiFi-R4CM-srv ~]# sed '2c null' a.txt #整行替换 注意:要真实替换文件里的内容需加-i
ID Name gender Mark
null
[root@MiWiFi-R4CM-srv ~]# sed 's/cc/test/g' a.txt #搜索替换 注意:要真实替换文件里的内容需加-i
ID Name gender Mark
3 test m 78
[root@MiWiFi-R4CM-srv ~]# sed -e 's/cc//g;s/78/99/g' a.txt #多条件执行 注意:要真实替换文件里的内容需加-i
ID Name gender Mark
3 m 99
字符处理命令
sort
排序命令
sort [选项] 文件名
选项:
-f 忽略大小写
-n 以数值类型进行排序,默认使用字符串类型排序
-r 反向排序
-t 指定分隔符,默认分隔符是制表符
-k n[,m] 按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行尾)
演示:
# 默认按字母排序 ,a排在第一个z最后一个
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd |cut -d ":" -f 1 |sort
adm
bin
chrony
daemon
dbus
dockerroot
ftp
games
halt
lp
mail
nobody
operator
polkitd
postfix
qilin
root
shutdown
sshd
sync
systemd-network
tg
user1
user2
yk
#反向排序
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd |cut -d ":" -f 1 |sort -r
yk
user2
user1
tg
systemd-network
sync
sshd
shutdown
root
qilin
postfix
polkitd
operator
nobody
mail
lp
halt
games
ftp
dockerroot
dbus
daemon
chrony
bin
adm
#指定分隔符,按第三个字段uid进行排序,如果不给结束范围会把后面的值同时拿来排序 注意:看排序的内容:他是以字符串进行排序:0 1 1000 1001....
#按理来说应该是0 1 2 3 这种;所以需要加入-n选项
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd|sort -t ":" -k 3,3
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
qilin:x:1000:1000:test user:/home/qilin:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
yk:x:1003:1004::/home/yk:/bin/bash
tg:x:1004:1006::/home/tg:/bin/bash
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
systemd-network:x:192:192:systemd Network Management:/:/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
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dockerroot:x:997:994:Docker User:/var/lib/docker:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
#以数值类型进行排序
[root@MiWiFi-R4CM-srv ~]# cat /etc/passwd|sort -n -t ":" -k 3,3
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
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dockerroot:x:997:994:Docker User:/var/lib/docker:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
qilin:x:1000:1000:test user:/home/qilin:/bin/bash
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
yk:x:1003:1004::/home/yk:/bin/bash
tg:x:1004:1006::/home/tg:/bin/bash
wc
统计命令
wc [选项] 文件名
选项:
-l: 值统计行数
-w: 只统计单词数量
-m:只统计字符数
[root@MiWiFi-R4CM-srv ~]# wc /etc/passwd
25 35 1111 /etc/passwd
#行数 单词数量 字符数 文件名
统计一个文件关键字出现的次数
[root@MiWiFi-R4CM-srv ~]# grep -o Name a.txt |wc -l
13
条件判断
按照文件类型进行判断
测试选项 | 作用 |
---|---|
-b 文件 | 判断该文件是否存在,并且是否为快设备文件(是块设备文件返回为真) |
-c 文件 | 判断该文件是否存在,并且为字符设备文件(是字符设备文件返回为真) |
-d 文件 | 判断该文件是否存在,并且是否为目录(是目录返回为真) |
-e 文件 | 判断该文件是否存在,(存在返回真) |
-f 文件 | 判断该文件是否存在,并且是否为普通文件(是普通文件返回为真) |
-L 文件 | 判断该文件是否存在,并且是否为符号链接文件(是符号链接文件返回为真) |
-p 文件 | 判断该文件是否存在,并且是否为管道文件(是管道文件返回为真) |
-s 文件 | 判断该文件是否存在,并且是否为非空(非空返回为真) |
-S 文件 | 判断该文件是否存在,并且是否为套接字文件(是套接字文件返回为真) |
两种判断格式
- test -e /root/install.log
- [-e /root/install.log]
[root@MiWiFi-R4CM-srv ~]# test -e a.txt
[root@MiWiFi-R4CM-srv ~]# echo $?
0
[root@MiWiFi-R4CM-srv ~]# [ -e a.txt ]
[root@MiWiFi-R4CM-srv ~]# echo $?
0
[root@MiWiFi-R4CM-srv ~]# [ -f a.txt ] && echo yes || echo no
yes
[root@MiWiFi-R4CM-srv ~]# [ -f /root ] && echo yes || echo no
no
按照文件权限判定
测试选项 | 作用 |
---|---|
-r 文件 | 判断文件是否存在,并且该文件是否拥有读权限(有读权限返回为真) |
-w 文件 | 判断文件是否存在,并且该文件是否拥有写权限(有写权限返回为真) |
-x 文件 | 判断文件是否存在,并且该文件是否拥有执行权限(有执行权限返回为真) |
-u 文件 | 判断文件是否存在,并且该文件是否拥有SUID权限(有SUID权限返回为真) |
-u 文件 | 判断文件是否存在,并且该文件是否拥有SGID权限(有SGID权限返回为真) |
-k 文件 | 判断文件是否存在,并且该文件是否拥有Sbit权限(有Sbit权限返回为真) |
两个文件之间比较
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新(如果新则为真) |
文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧(如果旧则为真) |
文件1 -ef 文件2 | 判断文件1和文件2的inode号是否一致,可以理解为两个文件是否是同一个文件。这个判断硬链接是很好的方法 |
两个整数之间的比较
测试选项 | 作用 |
---|---|
整数1 -eq 整数2 | 判断整数1和整数2是否相等(相等为真) |
整数1 -ne 整数2 | 判断整数1和整数2是否不相等(不相等为真) |
整数1 -gt 整数2 | 判断整数1是否大于整数2(大于为真) |
整数1 -lt 整数2 | 判断整数1是否小于整数2(小于为真) |
整数1 -ge 整数2 | 判断整数1是否大于等于整数2(大于等于为真) |
整数1 -le 整数2 | 判断整数1是否小于等于整数2(小于等于为真) |
字符串的判断
测试选项 | 作用 |
---|---|
-z 字符串 | 判断字符串是否为空(为空返回真) |
-n 字符串 | 判断字符串是否非空(非空返回真) |
字符串1==字符串2 | 判断字符串1是否和字符串2相等(相等返回真) |
字符串1!=字符串2 | 判断字符串1是否和字符串2不相等(不相等返回真) |
多重条件判断
测试选项 | 作用 |
---|---|
判断1 -a 判断2 | 逻辑与,判断1和判断2都成立,最红结果才为真 |
判断1 -o 判断2 | 逻辑或,判断1和判断2只要有一个成立,最终结果就为真 |
!判断 | 逻辑非,使原始的判断式取反 |
if条件判断
#!/usr/bin/bash
rate=$(df -h |grep /dev/mapper/centos-root|awk '{print $5}' |cut -d "%" -f 1)
if [ $rate -ge 90 ]
then
echo 'send message'
fi
echo $rate