您的位置:首页 > 运维架构 > Shell

Bash之正则表达式

2017-04-19 20:55 155 查看
正则表达式,又叫规则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。正则表达式分为基本正则表达式和扩展正则表达式,扩展正则表达式添加了一些更加丰富的匹配规则而成。
1 grep:文本查找、过滤工具。根据模式搜索文本,并将符合模式的文本显示出来。扩展的正则表达式有+、 ?、 |和()格式:grep [选项] [模式] file选项:-i 忽略大小写 -v 显示未被模式匹配的行 -c 显示多少行被匹配到
-n 显示行号 -r 递归查找
-o 仅显示匹配的字符串
--color 用颜色显示 -E 扩展正则表达式
查找包含root的行:[root@localhost log]# grep "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

验证crond服务是否存活:

[root@test ~]# ps aux | grep crond | grep -vc "grep"
1

查找包含至少一个r的行(*:匹配其前字符任意次)[root@localhost log]# grep --color "rr*" /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin

查找包含oot或ost的行([]:匹配范围内任意单个字符)
[root@localhost ~]# grep --color o[os]t /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin

查找包含数字0-9的行

[root@localhost ~]# grep --color [0-9] /etc/passwd
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

查找以root开始的行
[root@localhost ~]# grep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash

查找以nologin结尾的行[root@localhost ~]# grep "nologin$" /etc/passwd
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@localhost ~]# grep ^$ backpasswd

查看当前目录下包含root的行
[root@localhost ~]# grep -r root ./
./anaconda-ks.cfg:rootpw --iscrypted $6$K8rYflMst4cLGPIp$Dt8SHV9uPN/w4N3tQPAvyPFYjCCM5RHRRBcJf7NOP7MmqVFG1n0UYrfbgs7mDQ8KvobzHpC8R0Q3U.QUII38o.
./backpasswd:root:x:0:0:root:/root:/bin/bash
./backpasswd:operator:x:11:0:operator:/root:/sbin/nologin
./install.log:Installing rootfiles-8.1-6.1.el6.noarch
./install.log:Installing fakeroot-libs-1.12.2-22.2.el6.i686
./install.log:Installing fakeroot-1.12.2-22.2.el6.i686

查找出现数字2或5的行:[root@localhost ~]# egrep "(2|5)" c.txt
2
553

2 sed:行编辑器,适合编辑匹配到的文本,逐行处理文本文件,主要用于过滤和替换操作,适合处理大数据文件,sed默认并不直接修改源文件。

格式:sed [选项] [模式] file 其中模式如果是正则表达式,表示方式为:/正则表达式/选项:--help 显示帮助 -n 只显示匹配的行
-e 允许执行多个操作
-i 修改原文件
-f 指定文件
-r 使用扩展正则表达式模式: d 删除 p 打印
s 替换,如s/a/b/g,把a替换成b,g代表全局替换
w file 把模式空间的内容保存到文件中
a\ 在当前行后面加入文本 i\ 在当前行前面加入文本 r file 把文件内容添加到符合条件处 [root@localhost ~]# sed -n '1,2p' /etc/passwd #只打印前2行
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

[root@localhost ~]# sed -e '1,3p' -e '5d' c.txt #执行多个操作

[root@localhost ~]# sed -i 's/5/66/g' c.txt #直接修改源文件

[root@localhost ~]# sed '1,3d' c.txt #删除前3行

[root@localhost ~]# sed '1,3w /root/a.txt' c.txt #把1至3行保存到a.txt文件中

[root@localhost ~]# sed '2a\ccc' c.txt #在第2行后面添加ccc

[root@localhost ~]# sed '2i\ccc' c.txt #在第2行前面添加ccc

[root@localhost ~]# sed '/3$/a\abcdefg' c.txt #//表示正则匹配

[root@localhost ~]# vim d.sh #创建一个sed脚本
/^3/d

[root@localhost ~]# sed -f d.sh c.txt #以3开始的行被删除
66
66
66
660000

[root@localhost ~]# sed '2q' c.txt #显示前2行后退出
66
66

3 awk:是一种编程语言,也是优秀的报告生成器,按某种格式显示,是强大的数据处理引擎。
格式:awk [选项] '模式 {动作}' file... 其中模式如果是正则表达式,表示方式为:/正则表达式/
特殊模式:BEGIN:在没有读取任何数据之前执行
END:在所有数据读取完成之后执行
选项:-F 指定分隔符
-v value=a 在执行处理过程之前,设置一个变量

-f 从脚本文件中读取指令

内置记录变量:
OFS  指定输出字段分隔符,默认空格
ORS 输出时行分隔符
FS 输入字段分隔符,读取文本时使用,需要在BEGIN处定义,与-F类似
RS 输入文本信息所使用的换行符

内置数据变量:
NR 输入流的当前记录编号
FNR 输出多个文件的行编号
NF 当前记录的字段个数,$NF表示最后一个字段

printf:格式化字符串:
格式:printf("", );
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x, %X 无符号以十六进制表示的整数
%0 无符号以八进制表示的整数
%g 自动选择合适的表示法
\n 换行
\f 清屏并换页
\r 回车
\t Tab符
\xhh 表示一个ASCII码用16进表示,其中hh是1到2个16进制数
说明:
(1). 可以在"%"和字母之间插进数字表示最大场宽。
例如: %3d 表示输出3位整型数, 不够3位右对齐。
%9.2f 表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,小数点占一位, 不够9位右对齐。
%8s 表示输出8个字符的字符串, 不够8个字符右对齐。
如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出.但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出;若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出.
另外, 若想在输出值前加一些0, 就应在场宽项前加个0。
例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。
如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度,小数点前的数字代表最小宽度。
例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。

(2). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。
例如: %ld 表示输出long整数
%lf 表示输出double浮点数

(3). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。
例如: %-7d 表示输出7位整数左对齐
%-10s 表示输出10个字符左对齐

表达式和操作符
a=1 自定义变量
+ 加
- 减
> 大于
< 小于
&& 与
|| 或
== 等于
!= 不等于
~ 匹配
!~ 不匹配
......

[root@test ~]# awk -F : '{printf "%3d\n",$3}' a.txt 0 1 2 3 4 5 6 7 8 11

[root@test ~]# awk -F : '{printf "%-3d\n",$3}' a.txt
0
1
2
3
4
5
6
7
8
11

[root@test ~]# awk -F : '{printf "%8s\n",$1}' a.txt
root
bin
daemon
adm
lp
sync
 shutdown
halt
mail
 operator

[root@test ~]# awk -F : '{printf "%-10s%-10s\n",$1,$2}' a.txt
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
operator x
[root@test ~]# cat a.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

[root@test ~]# awk -v a="hello" 'BEGIN{print a}'
hello

[root@test ~]# awk -F : 'NR==3 {print $NF}' /etc/passwd
/sbin/nologin

[root@localhost ~]# awk '$1!~/ok/' a.txt
aaa
bb
ccabc

[root@localhost ~]# vim a.sh #编辑awk脚本
/^$/ {print "abc"} #通过正则匹配空白行,并打印abc
[root@localhost ~]# awk -f a.sh a.txt
abc
abc

[root@localhost ~]# awk -F : '{print $2,$3}' /etc/passwd #指定分隔符,打印2,3字段
x 0
x 1
x 2

[root@localhost ~]# echo a b c | awk '{print $NF}' #打印输出行最后一个字段
c

[root@localhost ~]# echo a b c | awk '{print NF}' #显示输出行字段的个数
3

[root@localhost ~]# echo a b c | awk 'BEGIN{OFS="-"}{print $1,$2,$3}' #输出分隔符
a-b-c

[root@test ~]# awk -F : 'BEGIN{OFS="##"} {print $1,"hello",$2}' a.txt
root##hello##x
bin##hello##x
daemon##hello##x
adm##hello##x
lp##hello##x
sync##hello##x
shutdown##hello##x
halt##hello##x
mail##hello##x
operator##hello##x

[root@localhost ~]# echo "cc" | awk 'a=3 {print a+1}' #自定义变量和计算
4

[root@test ~]# awk -F : '/^r/ {print $1}' /etc/passwd
root
rpc
rtkit
radvd
rpcuser
redis

[root@localhost ~]# awk -F : '$1~/root/ {print $3}' /etc/passwd #打印rootID号
0

[root@localhost ~]# awk -F : '$3>500 {print $1}' /etc/passwd #打印>500的ID号
nfsnobody
abc

[root@localhost ~]# df -h | grep "boot" | awk '{if($4<200) print "no" ;else print "ok"}'
no
#条件表达式,判断boot分区的空间,注意格式

[root@localhost ~]# awk 'BEGIN { print "line01\nline02\nline03\n"}'
line01
line02
line03

[root@localhost ~]# awk '{print NR}' a.txt #输入当前文件的行编号
1
2
3
4
5
6
7
8
9

[root@localhost ~]# awk '{print FNR}' a.sh a.txt #输出多个文件的行编号

[root@localhost ~]# awk -F : '$7!~/nologin$/ {print $7}' /etc/passwd
/bin/bash
/bin/sync
/sbin/shutdown
/sbin/halt

[root@localhost ~]# awk -F '[: ]' '{print $3}' a.txt #[]可以指定多个分隔符

[root@localhost ~]# awk -F : '$3==0 {print $0}' a.txt #过滤第三列等于0的行
root:x:0:0:root:/root:/bin/bash

[root@localhost ~]# awk -F : '$3==0 || $1=="lp" {print $0}' a.txt #比较字符串,加双引号
root:x:0:0:root:/root:/bin/bash
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

[root@localhost ~]# awk -F : '{print "username: " $1}' a.txt
username: root
username: bin
username: daemon
username: adm
username: lp
username: sync
username: shutdown
username: halt
username: mail
username: operator
username: 1334#
username: abcdeABd
username:
username: ccdoi
username: a b c d ef g

#下面是简单的awk脚本示例
[root@localhost ~]# cat a.awk
#!/usr/bin/awk -f
BEGIN {FS=":"}
{print $1,$2}

[root@localhost ~]# ./a.awk a.txt
root x
bin x
daemon x
adm x
lp x
sync x
shutdown x
halt x
mail x
operator x
1334#
abcdeABd

ccdoi
a b c d ef g
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 正则 表达式