5.41-5.46 正则三剑客
正则就是一串有规律的字符串,掌握好正则对于编写shell脚本有很大帮助,各种编程语言中都有正则,原理是一样的。
- grep/egrep:
格式:grep|egrep [-cinvABC] 'word' filename
例如:grep 'root' /etc/passwd
,表示过滤匹配包含关键词root的那一行内容并打印
[root@rice01 shell]# grep 'root' test
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
字段 | 含义 |
---|---|
-c | 过滤匹配包含关键词的行数 |
-i | 过滤匹配关键词不区分大小写 |
-n | 打印结果显示行号 |
-v | 取反 |
-r | 遍历所有子目录 |
-An | n为数字,过滤匹配符合要求的行以及下面n行 |
-B | 同上,过滤匹配符合要求的行以及上面n行 |
-C | 同上,过滤匹配符合要求的行以及上下各n行 |
'[ ]' | 方括号内为一个范围,它会过滤匹配范围内的单个字符 |
'^' | 过滤匹配以^ 后的字符为开头的关键词 |
'$' | 过滤匹配以$ 前的字符为结尾的关键词 |
'^$' | 表示空白字符 |
'.' | 表示单个任意字符,包含数字、字母、特殊符号 |
'*' | 过滤匹配包含* 前的字符的关键词(0个或多个) |
'.*' | 表示单个任意字符匹配任意次,即贪婪匹配 |
'+' | 过滤匹配包含+ 前的字符的关键词(1个或多个) |
'?' | 过滤匹配包含? 前的字符的关键词(0个或1个) |
'.*?' | 满足条件的情况只匹配一次,即最小匹配 |
'|' | 表示或者的意思 |
' { }' | 括号内为指定匹配括号前的关键词的个数,比如'a{2}' 表示关键词为aa , |
'( ){ }' | 花括号内为指定匹配小括号内的关键词的个数,比如'(ab){2}' 表示abab |
在定义''
内关键词时使用特殊符号必须以egrep开头,如果以grep开头就必须要在特殊符号前加转义字符\
- sed:
sed是一个“非交互式的”面向字符流的编辑器。能同时处理多个文件多行的内容,可以不对原文件改动,把整个文件输入到屏幕,可以把只匹配到模式的内容输入到屏幕上。还可以对原文件改动,但是不会再屏幕上返回结果。
sed的命令格式:sed [option] 'sed command' filename
sed的脚本格式:sed [option] -f 'sed script' filename
option:
字段 | 含义 |
---|---|
-n | 只打印模式匹配的行 |
-e | 直接在命令行模式上进行sed动作编辑,此为默认选项 |
-f | 将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作 |
-r | 支持扩展表达式 |
-i | 直接修改文件内容 |
sed在文件中查询文本的方式:
1)使用行号,可以是一个简单数字,或是一个行号范围
字段 | 含义 |
---|---|
x | x为行号 |
x,y | 表示行号从x到y |
/pattern | 查询包含模式的行 |
/pattern /pattern | 查询包含两个模式的行 |
pattern/,x | 在给定行号上查询包含模式的行 |
x,/pattern/ | 通过行号和模式查询匹配的行 |
x,y! | 查询不包含指定行号x和y的行 |
2)使用正则表达式、扩展正则表达式(必须结合-r选项)
字段 | 含义 |
---|---|
^ | 锚点行首的符合条件的内容,用法格式"^pattern" |
$ | 锚点行首的符合条件的内容,用法格式"pattern$" |
^$ | 空白行 |
. | 匹配任意单个字符 |
* | 匹配紧挨在前面的字符任意次(0,1,多次) |
.* | 匹配任意长度的任意字符 |
? | 匹配紧挨在前面的字符0次或1次 |
{m,n} | 匹配其前面的字符至少m次,至多n次 |
{m,} | 匹配其前面的字符至少m次 |
{m} | 精确匹配前面的m次{0,n}:0到n次 |
< | 锚点词首----相当于 \b,用法格式:<pattern |
> | 锚点词尾,用法格式:>pattern |
<pattern> | 单词锚点 |
[] | 匹配指定范围内的任意单个字符 |
[^] | 匹配指定范围外的任意单个字符 |
[:digit:] | 所有数字, 相当于0-9, [0-9]—> [[:digit:]] |
[:lower:] | 所有的小写字母 |
[:upper:] | 所有的大写字母 |
[:alpha:] | 所有的字母 |
[:alnum:] | 相当于0-9a-zA-Z |
[:space:] | 空白字符 |
[:punct:] | 所有标点符号 |
sed的编辑命令(sed command):
字段 | 含义 |
---|---|
p | 打印匹配行(和-n选项一起合用) |
= | 显示文件行号 |
a\ | 在定位行号后附加新文本信息 |
i\ | 在定位行号后插入新文本信息 |
d | 删除定位行 |
c\ | 用新文本替换定位文本 |
w filename | 写文本到一个文件,类似输出重定向 > |
r filename | 从另一个文件中读文本,类似输入重定向 < |
s | 使用替换模式替换相应模式 |
q | 第一个模式匹配完成后退出或立即退出 |
l | 显示与八进制ACSII代码等价的控制符 |
{} | 在定位行执行的命令组,用分号隔开 |
n | 从另一个文件中读文本下一行,并从下一条命令而不是第一条命令开始对其的处理 |
N | 在数据流中添加下一行以创建用于处理的多行组 |
g | 将模式2粘贴到/pattern n/ |
y | 传送字符,替换单个字符 |
sed引用变量:(在自动化shell脚本中也经常会使用到变量)
第一种当sed命令里面没有默认的变量时可以把单引号改成双引号;
第二种当sed命令里面有默认的变量时,那自己定义的变量需要加单引号,且sed里面的语句必须用单引
- awk:
打印头3行的第一段,以:
为分割符:
# head -3 test|awk -F ':' '{print $1}'
root
bin
daemon
打印头3行的,以:
为分割符:
# head -3 test|awk -F ':' '{print $0}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
也可以打印多段,并且可以指定输出结果的分隔符,如果使用,
,分隔符则为空格:
# head -5 test|awk -F ':' '{print $1,$2,$3}'
root x 0
bin x 1
daemon x 2
adm x 3
lp x 4
# head -5 test|awk -F ':' '{OFS="#"} {print $1,$2,$3}'
root#x#0
bin#x#1
daemon#x#2
adm#x#3
lp#x#4
查找匹配关键字的行:
# awk '/oo/' test // 匹配条件的字符串需要用//括起来,相当于grep 'oo' test和sed -n '/oo/'p test
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
也可以指定某一段进行过滤匹配:
# awk -F ':' '$1 ~/oo/' test // 指定第一段过滤匹配包含oo的行并打印出来,grep和sed是不能指定某一段进行过滤匹配的
root:x:0:0:root:/root:/bin/bash
也可以同时过滤匹配多个条件及打印多个行:
# awk -F ':' '$1 ~/root/ {print $1,$3} $1 ~/mysql/ {print $1,$3}' test
root 0
mysql 1000
进行比较运算过滤匹配:
# awk -F ':' '$3 == 0' test // $3等于数字0
# awk -F ':' '$3 == "0"' test // $3等于字符串0,如果不加""则为数字,加了就是字符串
# awk -F ':' '$3 >= "500"' test
# awk -F ':' '$3 >= 500' test
# awk -F ':' '$7 != "/sbin/nologin"' test
# awk -F ':' '$3 < $4' test
# awk -F ':' '$3 > "5" && $3 < "7"' test
# awk -F ':' '$3 > 1000 || $7 == "/bin/bash"' test
还可以加入if判断语句:
# awk -F ':' '{if ($3>1000) print $1,$2,$3,$4}' test
php-fpm x 1001 1001
ftpuser x 1002 1002
awk的其它用法:
# head -3 test|awk -F ':' '{print NF}' // NF示字段数,此为打印头三行的字段数
7
7
7
# head -3 test|awk -F ':' '{print NR}' // NR表示记录数,在执行过程中对应于当前的行号
1
2
3
# awk 'NR>20' test // 打印20行之后的内容
php-fpm:x:1001:1001::/home/php-fpm:/bin/bash
nginx:x:997:995:nginx user:/var/cache/nginx:/sbin/nologin
ftpuser:x:1002:1002::/home/ftpuser:/bin/bash
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
zabbix:x:996:994:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin
# awk -F ':' 'NR<10 && $1 ~/o/' test // 打印10行之前并且$1匹配字符o的行
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
# awk -F ':' '{(sum=sum+$3)};END {print sum}' test // 计算$3的和
7708