正则表达式grep,egrep,awk,sed工具
发布时间:2017-01-03 18:08:48 来源:51推一把
【摘要】在计算机科学中,正则表达式是这样解释的:它是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操
在计算机科学中,正则表达式是这样解释的:它是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。对于系统管理员来讲,正则表达式贯穿在我们的日常运维工作中,无论是查找某个文档,抑或查询某个日志文件分析其内容,都会用到正则表达式。
其实正则表达式,只是一种思想,一种表示方法。只要我们使用的工具支持表示这种思想那么这个工具就可以处理正则表达式的字符串。常用的工具有grep, sed, awk 等。
#grep
语法: grep [-cinvABC] ‘word’ filename
-c :打印符合要求的行数
-i :忽略大小写
-n :在输出符合要求的行的同时连同行号一起输出
-v :打印不符合要求的行
-A :后跟一个数字(有无空格都可以),例如 –A2则表示打印符合要求的行以及下面两行
-B :后跟一个数字,例如 –B2 则表示打印符合要求的行以及上面两行
-C :后跟一个数字,例如 –C2 则表示打印符合要求的行以及上下各两行
#[] 方括号的应用
[0-9]:数字
[a-zA-Z]:大小写字母
[^字符]:除了[]内之外的字符
eg:grep [^r]oo /etc/passwd #筛选不包含r,包含oo的字符串
#^,$ ^以某个字符开头,$以某个字符尾
eg:grep ‘^r’ /etc/passwd #以r开头的字符串
eg:grep ‘h$’/etc/passwd #以h结尾的字符串
”^$” #空行
eg:grep -v ‘^$’ filename #筛选出非空行
eg:grep ^[^a-zA-Z] test.txt #筛选非字母开头的字符串
#.,* .表示任意一个字符,*表示0个或多个前面的字符
eg: grep r..o /etc/passwd #把符合r与o之间有两个任意字符的行过滤出来
eg: grep ooo* /etc/passwd #‘ooo*’ 表示oo, ooo, oooo … 或者更多的’o’
‘.*’表示零个或多个任意字符,空行也包含在内。
eg: grep .* /etc/passwd |wc -l
#{} 重复次数
eg: grep o\{2\} /etc/passwd #{ }左右都需要加上脱意字符’\’,也可表示范围‘\{n1,n2\}’其中n1
#egrep
a. 筛选一个或一个以上前面的字符
eg: egrep o+ /etc/passwd #和grep 不同的是,egrep这里是使用’+’的
b. 筛选零个或一个前面的字符
eg: egrep o? /etc/passwd
c. 筛选字符串1或者字符串2
eg:egrep 111|aaa /etc/passwd #|表示或的意思
d. egrep中’( )’的应用
eg: egrep r(oo)|(at)o /etc/passwd #用’( )’表示一个整体,例如(oo)+就表示1个’oo’或者多个’oo’
grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。
以前用vim的时候,可以查找也可以替换,但是只局限于在文本内部来操作,而不能输出到屏幕上。
sed工具以及awk工具就能实现把替换的文本输出到屏幕上的功能了,而且还有其他更丰富的功能。
sed和awk都是流式编辑器,是针对文档的行来操作的。
#sed
a. sed -n np filename #单引号内的n是一个数字,表示第几行
eg: sed -n 2 /etc/passwd #打印出第二行
b. sed -n 1,$p filename #打印多行或整个文档 $表示最后一行
eg: sed -n 2,5p /etc/passwd #打印2至5行
sed -n 1,$p /etc/passwd #打印所有行
c. sed -n /word/p filename #打印包含某个字符串的行
eg: sed -n /root/p /etc/passwd
ps:上面grep中使用的特殊字符,如’^’, ‘$’, ‘.’, ‘*’等同样也能在sed中使用。
d. sed -e 1p -e /1111/p -n filename #-e 可以实现多个行为
eg: sed -e 1p -e /test/p -n /etc/password #打印出第一行和包含test的行
e. sed 1d filename; sed 1,5d filename #删除某行或多行,引号中间可以是数字,也可以条件。
eg: sed 1d /etc/passwd
sed 1,3d /etc/passwd
sed /root/d /etc/passwd
f. sed 1,2s/ot/to/g filename #替换字符或字符串 s就是替换的命令,g为本行中全局替换,如果不加g,只换该行中出现的第一个。
eg: sed 1,2s/ot/to/g /etc/passwd
ps:除了可以使用/’外,还可以使用其他特殊字符例如’#’或者’@’
eg: sed 1,2s#ot#to#g /etc/passwd
eg: sed 1,2s@ot@to@g /etc/passwd
eg: sed s/[0-9]//g /etc/passwd #删除文档中所有数字
g. sed s/\(root\)\(.*\)\(bash\)/\3\2\1/ filename #调换两个字符串的位置
ps:()把所想要替换的字符括起来成为一个整体,因为括号在sed中属于特殊符号,所以需要在前面加脱意字符’\’,替换时则写成’\1’, ‘\2’, ‘\3’ 的形式。
除了调换两个字符串的位置外,还常常用到在某一行前或者后增加指定内容。
f. sed -i ‘s/:/#/g’ test.txt #直接修改文件的内容
这样就可以直接更改test.txt文件中的内容了。由于这个命令可以直接把文件修改,所以在修改前最好先复制一下文件以免改错。
#awk工具的使用
awk工具其实是很复杂的,有专门的书籍来介绍它的应用。
常见的awk应用如下,感兴趣的话,可以去深入研究。
a. 截取文档中的某个段
#head -n2 /etc/passwd |awk -F: {print $1} -F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。
head -n2 /etc/passwd |awk {print $2,$3} eg: my name is Amie 结果为my name
$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。
注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用’{ }’括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用双引号括起来。
eg: head -n2 /etc/passwd |awk -F: {print $1"@"$2"xxxx"$3}
b. 匹配字符或字符串
awk /root/ /etc/passwd
awk -F: $1~/root/ /etc/passwd #让某个段去匹配,这里的’~’就是匹配的意思
awk -F: /root/ {print $3} /test/ {print $3} /etc/passwd #awk还可以多次匹配,如匹配完root,再匹配test,它还可以只打印所匹配的段
awk -F: $1~/root/ {print $1} /etc/passwd
c. 条件操作符
awk -F: $3=="0" /etc/passwd
awk中是可以用逻辑符号判断的,比如’==’就是等于,也可以理解为“精确匹配”。
另外也有’>’, ‘>=’, ‘<’, ‘<=’, ‘!=’ 等等,值得注意的是,即使$3为数字,awk也不会把它当数字看待,它会认为是一个字符。所以不要妄图去拿$3当数字去和数字做比较。这里只是字符
与字符之间的比较。
awk -F: $7!="/sbin/nologin" /etc/passwd # !=即不匹配
awk -F: $3<$4 /etc/passwd
awk -F: $3<"5" && $4>"9" /etc/passwd #可以使用”&&” 和 “||”表示“并且”和“或者”
awk -F: $3<"5" || $4>"9" /etc/passwd
d. awk的内置变量
常用的变量有:
NF :用分隔符分隔后一共有多少段;
NR :行数
awk -F: {print NF} /etc/passwd |head -n 5 #打印总段数
awk -F: {print $NF} /etc/passwd |head -n 5 #打印最后一段的值
awk -F: NR>=20 && $1~/ssh/ /etc/passwd #使用NR作为条件,来打印出指定的行
e. awk中的数学运算
head -n 5 /etc/passwd |awk -F: $1="root" #第一段赋值
head -n 2 /etc/passwd |awk -F: {$7=$3+$4;print $3,$4,$7}
cat /etc/passwd |awk -F: {(tot+=$3)};END {print tot} #计算某个段的总和
这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法,其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用if判断、for循环都是可以的
awk -F: {if ($1=="root") print $0} /etc/passwd
基本上,正则表达的内容就这些了。但是这些仅仅是最基本的东西,可以满足日常工作的需要,有时候也许你会碰到比较复杂的需求,如果真遇到了就去请教一下google吧。
其实正则表达式,只是一种思想,一种表示方法。只要我们使用的工具支持表示这种思想那么这个工具就可以处理正则表达式的字符串。常用的工具有grep, sed, awk 等。
#grep
语法: grep [-cinvABC] ‘word’ filename
-c :打印符合要求的行数
-i :忽略大小写
-n :在输出符合要求的行的同时连同行号一起输出
-v :打印不符合要求的行
-A :后跟一个数字(有无空格都可以),例如 –A2则表示打印符合要求的行以及下面两行
-B :后跟一个数字,例如 –B2 则表示打印符合要求的行以及上面两行
-C :后跟一个数字,例如 –C2 则表示打印符合要求的行以及上下各两行
#[] 方括号的应用
[0-9]:数字
[a-zA-Z]:大小写字母
[^字符]:除了[]内之外的字符
eg:grep [^r]oo /etc/passwd #筛选不包含r,包含oo的字符串
#^,$ ^以某个字符开头,$以某个字符尾
eg:grep ‘^r’ /etc/passwd #以r开头的字符串
eg:grep ‘h$’/etc/passwd #以h结尾的字符串
”^$” #空行
eg:grep -v ‘^$’ filename #筛选出非空行
eg:grep ^[^a-zA-Z] test.txt #筛选非字母开头的字符串
#.,* .表示任意一个字符,*表示0个或多个前面的字符
eg: grep r..o /etc/passwd #把符合r与o之间有两个任意字符的行过滤出来
eg: grep ooo* /etc/passwd #‘ooo*’ 表示oo, ooo, oooo … 或者更多的’o’
‘.*’表示零个或多个任意字符,空行也包含在内。
eg: grep .* /etc/passwd |wc -l
#{} 重复次数
eg: grep o\{2\} /etc/passwd #{ }左右都需要加上脱意字符’\’,也可表示范围‘\{n1,n2\}’其中n1
#egrep
a. 筛选一个或一个以上前面的字符
eg: egrep o+ /etc/passwd #和grep 不同的是,egrep这里是使用’+’的
b. 筛选零个或一个前面的字符
eg: egrep o? /etc/passwd
c. 筛选字符串1或者字符串2
eg:egrep 111|aaa /etc/passwd #|表示或的意思
d. egrep中’( )’的应用
eg: egrep r(oo)|(at)o /etc/passwd #用’( )’表示一个整体,例如(oo)+就表示1个’oo’或者多个’oo’
grep实现的只是查找功能,而它却不能实现把查找的内容替换掉。
以前用vim的时候,可以查找也可以替换,但是只局限于在文本内部来操作,而不能输出到屏幕上。
sed工具以及awk工具就能实现把替换的文本输出到屏幕上的功能了,而且还有其他更丰富的功能。
sed和awk都是流式编辑器,是针对文档的行来操作的。
#sed
a. sed -n np filename #单引号内的n是一个数字,表示第几行
eg: sed -n 2 /etc/passwd #打印出第二行
b. sed -n 1,$p filename #打印多行或整个文档 $表示最后一行
eg: sed -n 2,5p /etc/passwd #打印2至5行
sed -n 1,$p /etc/passwd #打印所有行
c. sed -n /word/p filename #打印包含某个字符串的行
eg: sed -n /root/p /etc/passwd
ps:上面grep中使用的特殊字符,如’^’, ‘$’, ‘.’, ‘*’等同样也能在sed中使用。
d. sed -e 1p -e /1111/p -n filename #-e 可以实现多个行为
eg: sed -e 1p -e /test/p -n /etc/password #打印出第一行和包含test的行
e. sed 1d filename; sed 1,5d filename #删除某行或多行,引号中间可以是数字,也可以条件。
eg: sed 1d /etc/passwd
sed 1,3d /etc/passwd
sed /root/d /etc/passwd
f. sed 1,2s/ot/to/g filename #替换字符或字符串 s就是替换的命令,g为本行中全局替换,如果不加g,只换该行中出现的第一个。
eg: sed 1,2s/ot/to/g /etc/passwd
ps:除了可以使用/’外,还可以使用其他特殊字符例如’#’或者’@’
eg: sed 1,2s#ot#to#g /etc/passwd
eg: sed 1,2s@ot@to@g /etc/passwd
eg: sed s/[0-9]//g /etc/passwd #删除文档中所有数字
g. sed s/\(root\)\(.*\)\(bash\)/\3\2\1/ filename #调换两个字符串的位置
ps:()把所想要替换的字符括起来成为一个整体,因为括号在sed中属于特殊符号,所以需要在前面加脱意字符’\’,替换时则写成’\1’, ‘\2’, ‘\3’ 的形式。
除了调换两个字符串的位置外,还常常用到在某一行前或者后增加指定内容。
f. sed -i ‘s/:/#/g’ test.txt #直接修改文件的内容
这样就可以直接更改test.txt文件中的内容了。由于这个命令可以直接把文件修改,所以在修改前最好先复制一下文件以免改错。
#awk工具的使用
awk工具其实是很复杂的,有专门的书籍来介绍它的应用。
常见的awk应用如下,感兴趣的话,可以去深入研究。
a. 截取文档中的某个段
#head -n2 /etc/passwd |awk -F: {print $1} -F 选项的作用是指定分隔符,如果不加-F指定,则以空格或者tab为分隔符。
head -n2 /etc/passwd |awk {print $2,$3} eg: my name is Amie 结果为my name
$1为第一个字段,$2为第二个字段,依次类推,有一个特殊的那就是$0,它表示整行。
注意awk的格式,-F后紧跟单引号,然后里面为分隔符,print的动作要用’{ }’括起来,否则会报错。print还可以打印自定义的内容,但是自定义的内容要用双引号括起来。
eg: head -n2 /etc/passwd |awk -F: {print $1"@"$2"xxxx"$3}
b. 匹配字符或字符串
awk /root/ /etc/passwd
awk -F: $1~/root/ /etc/passwd #让某个段去匹配,这里的’~’就是匹配的意思
awk -F: /root/ {print $3} /test/ {print $3} /etc/passwd #awk还可以多次匹配,如匹配完root,再匹配test,它还可以只打印所匹配的段
awk -F: $1~/root/ {print $1} /etc/passwd
c. 条件操作符
awk -F: $3=="0" /etc/passwd
awk中是可以用逻辑符号判断的,比如’==’就是等于,也可以理解为“精确匹配”。
另外也有’>’, ‘>=’, ‘<’, ‘<=’, ‘!=’ 等等,值得注意的是,即使$3为数字,awk也不会把它当数字看待,它会认为是一个字符。所以不要妄图去拿$3当数字去和数字做比较。这里只是字符
与字符之间的比较。
awk -F: $7!="/sbin/nologin" /etc/passwd # !=即不匹配
awk -F: $3<$4 /etc/passwd
awk -F: $3<"5" && $4>"9" /etc/passwd #可以使用”&&” 和 “||”表示“并且”和“或者”
awk -F: $3<"5" || $4>"9" /etc/passwd
d. awk的内置变量
常用的变量有:
NF :用分隔符分隔后一共有多少段;
NR :行数
awk -F: {print NF} /etc/passwd |head -n 5 #打印总段数
awk -F: {print $NF} /etc/passwd |head -n 5 #打印最后一段的值
awk -F: NR>=20 && $1~/ssh/ /etc/passwd #使用NR作为条件,来打印出指定的行
e. awk中的数学运算
head -n 5 /etc/passwd |awk -F: $1="root" #第一段赋值
head -n 2 /etc/passwd |awk -F: {$7=$3+$4;print $3,$4,$7}
cat /etc/passwd |awk -F: {(tot+=$3)};END {print tot} #计算某个段的总和
这里的END要注意一下,表示所有的行都已经执行,这是awk特有的语法,其实awk连同sed都可以写成一个脚本文件,而且有他们特有的语法,在awk中使用if判断、for循环都是可以的
awk -F: {if ($1=="root") print $0} /etc/passwd
基本上,正则表达的内容就这些了。但是这些仅仅是最基本的东西,可以满足日常工作的需要,有时候也许你会碰到比较复杂的需求,如果真遇到了就去请教一下google吧。