正则表达式与三剑客的使用技巧
原文:http://blog.51cto.com/hujiangtao/1923177
1.正则表达式的基础
^ ^锚定行的开始如:/^sed/匹配所有以sed开头的行
$ $锚定行的结束 如:/sed$/匹配所有以sed结尾的行
. .匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d
? 代表前趋字符的一次出现
* *匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行
[] 匹配指定范围内的任意单个字符,如/[Ss]ed/匹配sed和Sed
[^] 匹配指定范围外的任意单个字符
如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行
/< 锚定单词的开始,如:/<love/匹配包含以love开头的单词的行
/> 锚定单词的结束,如/love>/匹配包含以love结尾的单词的行
/( /) 引用标识,可以多次引用,并在后面以/1 /2来引用
x/{m,n/} 代表x的至少m次,至多n次出现
| 用于使用多个正则条件,匹配之一即可
+ 与. *类似,表示1个或多个重复字符
() 用于将多个内容组成单元组
(..) 保存匹配的字符,如s/(love)able/1rs,loveable被替换成lovers
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**
x{m} 重复字符x,m次,如:/0{5}/匹配包含5个o的行
x{m,} 重复字符x,至少m次,如:/o{5,}/匹配至少有5个o的行
x{m,n} 重复字符x,至少m次,不多于n次,如:/o{5,10}/匹配5--10个o的行
2.grep
作用:文本搜索工具,根据用户指定的"模式(过滤条件)"对目标文本逐行进行匹配检查;打印匹配的行
模式:有正则表达式的元字符及文本字符所编写的过滤条件
正则表达式引擎:
grep [OPTIONS] [PATTERN] [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
常用选项:
--color=auto 对匹配到的文本着色后高亮显示
-E 使用正则扩展
-e pattern 使用pattern中的正则
-f file 使用文件中的正则
-i 忽略大小写(性能较差,最好先用tr统一转换成大写或小写)
-o 仅显示匹配到字符串本身;
-v 反向显示不匹配的行
-V 显示版本号
输出控制选项:
-n 输出行号
-q 不显示未匹配的内容
-r 递归方式扫描文件
-l 只输出匹配的文件名
-L 只输出不匹配的文件名
-c 只显示匹配的个数
-A 匹配的到后面几行也显示出来
-B 匹配的到前面几行也显示出来
-C 上下文,匹配的到前后面几行也显示出来
匹配次数:用在要指定其出现的次数的字符的后面,用户限制其前面字符出现的次数
: 匹配器前面的字符任意次:0,1,多次
例如:grep "xy",abxy aby xxxy yab
.* 匹配任意长度的任意字符,贪婪模式,能匹配多长就匹配多长
? 匹配其前面的字符0次或者1次;即其前面的字符可有可无的
+ 匹配其前面的字符一次或多次;即其前面的字符出现至少1次
{m} 匹配其前面的字符m次
{m,n} 匹配其前面的字符至少m次,至多n次
{0,n} 至多n次
{m,} 至少m次
位置锚定:
^ 行首锚定;用于模式的最左侧
$ 行尾锚定;用于模式的最右侧
^PATTERN$ 用PATTERN来匹配整行
^$ 空白行
^[[:space:]]*$ 空行或包含空白字符的行
单词: 非特殊字符组成的连续字符(字符串)都为单词
< 或 词首锚定,用于单词模式的左侧,例如:grep "<word"
> 或 词尾锚定,用于单词模式的右侧,例如:grep "word>"
<PATTERN> 匹配完整单词
分组及引用:
() 将一个或多个字符捆绑在一起,当作一个整体进行处理,例如:(xy)*ab
Note 分组括号中的模式匹配到的内容会被正则表达式引擎自动记录到内部的变量中,这些变量为:
1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符
2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符
3:后向引用,引用前面的分组括号中的模式所匹配到的字符
常用示例:
1、显示/etc/passwd文件中不以/bin/bash结尾的行
grep -v "/bin/bash$" /etc/passwd
2、找出/etc/passwd文件中的两位数或三位数
grep "<[[:digit:]]{2,3}>" /etc/passwd
3、找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行
grep "^[[:space:]]+[^[:space:]]" /etc/grub2.cfg
4、找出"netstat -tan"命令的结果中以"LISTEN"后跟0、1或多个空白字符结尾的行
netstat -tan|grep "LISTEN[[:space:]]*$"
5、grep "(l..e).*1" lovers.txt
He loves his lover.
He likes his lover.
She likes her liker.
She loves her liker.
6、grep -i 'root' /etc/passwd 不区分大小写显示文件中有root的行
7、grep -v '^root' /etc/passwd 显示文件中开关不是root和行
8、grep -n 'root' /etc/passwd 显示文件中含有root的行,且打印此行在文件中的行号
9、grep -lr '$root' /etc 递归查找/etc下包含行结尾为root的文件名
10、grep -Lr 'root' /etc 递归查找/etc下文件中不包含root的文件名
11、grep -c 'root' /etc/passwd 统计文件中root出现的行数
12、grep "hello | world" 1.cpp 匹配包含hello的行和world的行
egrep命令:支持扩展正则表达式实现类似于grep文本过滤功能:grep -E
正则表达式引擎:egrep [OPTINS] PATTERN [FILE]
选项:与grep选项相似
-G:支持基本正则表达式
扩展正则表达式的元字符:
字符匹配:
. 匹配任意单个字符
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
次数匹配:
: 匹配器前面的字符任意次:0,1,多次
.: 匹配任意长度的任意字符,贪婪模式,能匹配多长就匹配多长
? 匹配其前面的字符0次或者1次;即其前面的字符可有可无的
+ 匹配其前面的字符一次或多次;即其前面的字符出现至少1次
{m} 匹配其前面的字符m次
{m,n} 匹配其前面的字符至少m次,至多n次
{0,n} 至多n次
{m,} 至少m次
位置锚定:
^ 行首锚定;用于模式的最左侧
$ 行尾锚定;用于模式的最右侧
<或 词首锚定,用于单词模式的锚定
>或 词尾锚定,用于单词模式的锚定
分组及引用:
() 分组;括号内模式匹配到的字符会被记录到正则表达式引擎的内部变量中
后向引用:1,2....或:
a|b a或b
C|cat C或cat
(c|C)at cat或Cat
常用示例:
1、找出/proc/meminfo文件中,所有以大写或小写S开头的行;至少有三种实现方式
grep "^[sS]" /proc/meminfo
grep -i "^sS" /proc/meminfo
grep -E "^(s|S)" /proc/meminfo
grep -E "^s|^S" /proc/meminfo
2、显示当前系统上root、centos或者user1用户的相关信息
grep -E "^(root|centos|user1>)" /etc/passwd
3、找出/etc/rc.d/init.d/functions文件中某单词后跟一个小括号的行
grep -Eo '_[[:alnum:]]+()' /etc/rc.d/init.d/functions
4、使用echo命令输出一绝对路径,使用egrep取出基名
echo "/root/ssf/erou/dfjl" | egrep -o "<[[:alpha:]]>$" echo "/root/ssf/erou/dfjl" | grep -Eo "[^/]+/?$"
5、找出ifconfig命令结果中的1-255之间的数值
ifconfig | grep -oE "<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])>"
6、添加用户bash, testbash, basher以及nologin(其shell为/sbin/nologin)
而后找出/etc/passwd文件中用户名同shell名的行
grep -E "^([^:]+>).1$" /etc/passwd
3.sed
sed命令行格式为:sed [-nefri] ‘command’ 输入文本/文件
常用选项:
-f 指定过滤脚本文件名
-e 后跟匹配表达式
-n 不显示默认输出
-r sed 的动作支援的是延伸型正则表达式的语法
-i 直接修改读取的文件内容,而不是由屏幕输出
常用命令:
a ∶ 新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c ∶ 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d ∶ 删除,因为是删除,所以 d 后面通常不接任何内容
i ∶ 插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
p∶ 列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起用
s∶ 取代,可以直接进行替换的工作。通常这个 s 的动作可以搭配正则表达式。例如 1,20s/old/new/g
sed脚本上的命令:
sed '/root/a/text' /etc/passwd 在文件的root那一行后增加新行text
sed '/root/c/text' /etc/passwd 在文件的root那一行替换为text
sed '/root/i/text' /etc/passwd 在匹配行前插入text
sed '/root/d' /etc/passwd 删除文件中含有root的那一行
h/H 复制或附加模式缓冲区到一个buffer
g/G 从buffer中取出并复制或附加到当前模式缓冲区
sed -e '/root/{h;d;}' -e '$g' /etc/passwd 将root行放在最后一行
p 打印行
sed -n '/root/{n;p;}' /etc/passwd 打印root行的下一行
sed '1,3y/abcdef/ABCDEF/' /etc/passwd 映射1-3行的小写为大写
s/xxx/yyy/g 文本替换
sed定址:
sed -n '1,3p' /etc/passwd 打印文件1-3行
sed -n '/root/,/sshd/p' /etc/passwd 打印文件root行与sshd行之间的行
sed -n '5,/^northeast/p' file
实例分享:
1、复制/etc/inittab文件至/tmp/目录,替换/tmp/inittab文件中的"id:3:initdefault"一行数字为5
1
|
# cp /etc/inittab /tmp/# sed's/id:3:initdefault/id:5:initdefault/' /tmp/inittab |
2、复制/etc/rc.d/init.d/functions文件至/tmp目录,删除/tmp/functions文件的空白行
1
|
# cp /etc/rc.d/init.d/functions/tmp/# sed '/^[[:space:]]*$/d'/tmp/functions |
3、复制/boot/grub/grub.conf文件至/tmp/目录,删除/tmp/grub.conf文件中行首的空白字符
1
|
# cp /boot/grub/grub.conf /tmp/# sed 's@^[[:space:]]+@@'/tmp/grub.conf |
4、echo一个路径给sed,通过sed取出其路径名
例如echo"etc/sysconfig/network-scripts/" | sed,返回路径名/etc/sysconfig/
1
|
# echo"/etc/sysconfig/network-scripts/" | sed 's@[^/]+/?$@@' |
4.awk
awk命令主要用于文本内容的分析处理
如果对处理的数据需要生成报告之类的信息,或者处理的数据是按列进行处理的,最好使用awk
awk读入有’ ’换行符分割的一条记录,然后将记录按指定的域分隔符划分域
$0则表示所有域,$1表示第一个域,$n表示第n个域
awk是一个报告生成工具,旨在把文件中读取到的每一行的每个字段分别进行格式化
而后进行显示,awk支持使用变量、条件判断、循环、数组
比如说,以”:”分隔filename文本的每一行并且打印第一列
awk -F ':' '{print $1}' filename
通用格式:gawk 'pattern {action}' file
cmd | gawk 'pattern {action}'
工作原理:awk 扫描一行,放入变量$0中,然后行被分隔成各个域
以指定的分隔符进行分离,默认为空格,可以通过参数FS指定。各个域都存于变量$i中,至多100个域
sed和awk定制化显示举例
这里,我们可以制作一个文本my.txt,内容为:
This is my cat, my cat's name is betty
This is my dog, my dog's name is frank
This is my fish, my fish's name is george
This is my goat, my goat's name is adam
需要显示的结果为:
cat:betty
dog:frank
fish:george
goat:adam
如果采用sed,可以输入
sed 's/This is my (.*),.*is (.*)/1:2/g' my.txt
如果采用awk,则有两种方法
awk -F '[ ,]' '{print $4,$10}' OFS=":" my.txt
awk -F '[ ,]' '{printf("%s:%s ",$4,$10)}' my.txt
1.显示GID小于500的组
awk -F : '$3<500{print $1}' /etc/group
2.显示默认的shell为nologin的用户
awk -F : '$7~/nologin$/{print $1}' /etc/passwd
3.显示eth0网卡文件的配置信息,注意,只显示等号后面的值
awk -F = '{print $2}' /etc/sysconfig/network-scripts/ifcfg-eth0
4.显示/etc/sysctl。conf文件中定义的内核参数:只显示名称
awk -F =' !/^#|^$/{print $1}'/etc/sysctl.conf
5.显示eth0网卡的ip地址,通过ifconfig命令结果进行过滤
ifconfig eth0 |awk '/inet addr/{print $2}' |awk -F : '{print $2}'