简单而言,正则表达式通过一些特殊符号的帮助,使用户可以轻松快捷的完成查找、删除、替换等处理程序。
一些特殊符号的表示
[:alnum:]代表英文大小写字母及数字
[:alpha:]代表英文大小写字母
[:blank:]代表空格和 tab 键
[:cntrl:]键盘上的控制按键,如 CR,LF,TAB,DEL
[:digit:]代表数字
[:graph:]代表空白字符以外的其他
[:lower:]小写字母
[:print:]可以被打印出来的任何字符
[:punct:]代表标点符号
[:upper:]代表大写字符
[:space:]任何会产生空白的字符如空格,tab,CR 等
[:xdigit:]代表16进制的数字类型
grep命令可以使用正则表达式搜索文本,并把匹配的行打印出来,其常用方法如下:
grep [-acinv] [--color=auto] '搜寻字符串' filename
选项与参数:
-a :将 binary 文件以 text 文件的方式搜寻数据
-c :计算找到 '搜寻字符串' 的次数
-i :忽略大小写的不同,所以大小写视为相同
-n :顺便输出行号
-v :反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行!
--color=auto :可以将找到的关键词部分加上颜色的显示
case1
查找特定的字符串
grep -n 'the' regular_express.txt # 查找'the' 字符串
case2
字符组匹配,[]中包含的任意一个字符,只能是一个,字符组支持”-“连字符来表示一个范围,[^ ...]
是排除型字符组,用来排除后面的字符
[abc] :表示“a”或“b”或“c”
[0-9] :表示 0~9 中任意一个数字,等价于[0123456789]
[\u4e00-\u9fa5] :表示任意一个汉字
[^a1<] :表示除“a”、“1”、“<”外的其它任意一个字符
[^a-z] :表示除小写字母外的任意一个字符
grep -n 't[ae]st' regular_express.txt # 查找“tast”或者“test”两个字符串
grep -n '[^#]' regular_express.txt #查找不包含“#”的字符串
grep -n '[^g]oog' regular_express.txt # 查找"oog",但是不查找"goog"
grep -n '[^go]oog'regular_express.txt# 查找"oog",但是不查找"goog"和"ooog"
grep -n '[[:lower:]]' regular_express.txt # 查找小写字母
case3
行首符^,行尾符$,具体应用如下
grep -n '^the' regular_express.txt # 查找行首为"the"的所有行
grep -n '^[A-Z]' regular_express.txt # 查找行首为大写字母的所有行
grep -n '[^A-Z]' regular_express.txt # 查找除了大写字母以外的所有字符,注意和上面区分
grep -n 'd$' regular_express.txt # 查找以"d"结尾的所有行
grep -n '^$' regular_express.txt # 查找空行
case4
grep的反向选择和管道线联合应用
grep -v '^$' /etc/insserv.conf | grep -v '^#' # 先过滤掉空白行,然后过滤掉注释行(以#开头)
case5
小数点”.”表示任意一个字符,星号”*”表示重复的字符
grep -n 'a.ou.' regular_express.txt # 查找a?ou?类型的字符
*(星号):代表重复前面0个或者多个字符。
e*: 表示具有空字符或者一个以上e字符。
ee*,表示前面的第一个e字符必须存在。第二个e则可以是0个或者多个e字符。
eee*,表示前面两个e字符必须存在。第三个e则可以是0个或者多个e字符。
ee*e :表示前面的第一个与第三个e字符必须存在。第二个e则可以是0个或者多个e字符。
case6
大括号{}可以限定一个范围区间重复的字符数,注意,必须用转义字符来表示这个大括号,即为\{\}
,否则出错。
grep -n 'o\{2\}' regular_express.txt # 查找连续的两个"o"
grep -n 'go\{2,5\}g' regular_express.txt # 查找g后面接2到5个o,然后再接g的字符串
小结
^word 表示带搜寻的字符串(word)在行首
word$ 表示带搜寻的字符串(word)在行尾
.(小数点) 表示1个任意字符
\ 表示转义字符,在特殊字符前加\会将特殊字符意义去除
* 表示重复0到无穷多个前一个RE(正则表达式)字符
[list] 表示搜索含有l,i,s,t任意字符的字符串
[n1-n2] 表示搜索指定的字符串范围,例如[0-9] [a-z] [A-Z]等
[^list] 表示反向字符串的范围,例如[^0-9]表示非数字字符,[^A-Z]表示非大写字符范围
\{n,m\} 表示找出n到m个前一个RE字符
\{n,\} 表示n个以上的前一个RE字符
sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。sed 编辑器逐行处理文件(或输入),并将结果发送到屏幕。其常用方法如下:
sed [-nefri] ‘command’ 输入文本
常用选项:
-n:使用安静(silent)模式。如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
-e:直接在指令列模式上进行 sed 的动作编辑;
-f:直接将 sed 的动作写在一个档案内,-f filename则可以执行 filename 内的sed 动作;
-r:sed的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
-i:直接修改读取的档案内容,而不是由屏幕输出。
常用命令:
a:新增,a的后面可以接字串,而这些字串会在当前行的下一行
c:取代,c的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d:删除,因为是删除,所以d后面通常不接任何内容
i:插入,i的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行)
p:打印,将某个选择的部分打印出。通常p会与参数sed -n一起运作(仅打印需要的行)
s:替换,可以直接进行替换的工作,通常s动作可以搭配正规表示法
case1
nl regular_express.txt | sed '2,5d' # 将 regular_express.txt 的内容列出并打印行号,同时,将2-5 行删除显示
nl regular_express.txt | sed '2d' # 同上,仅删除第二行
nl regular_express.txt | sed '3,$d' #同上,删除第3行到最后一行
sed -i '1d' regular_express.txt # 在原文件中删除第 1 行
case2
a表示在行后加上字符串,i表示在行前添加字符串
nl regular_express.txt | sed '2a test' # 在第二行后添加 test 字符串
nl regular_express.txt | sed '2i test' # 在第二行前添加 test 字符串
nl regular_express.txt | sed '2a test\ntest' # 在第二行后加入两行 test,“\n”表示换行符
case3
c 为替换内容选项
nl regular_express.txt | sed '2,5c No 2-5 number' # 将 2-5 行内容取代为"No 2-5 number"
case4
sed ‘s/被替换字符串/新字符串/g’
/sbin/ifconfig eth0 |grep 'inet ' # 在/sbin/ifconfig eth0 的结果中查找‘inet’,打印至终端
# 结果是inet addr:192.168.40.12 Bcast:0.0.0.0 Mask:255.255.255.0
/sbin/ifconfig eth0 |grep 'inet '| sed 's/inet ....://g' # 将IP地址前的字符去掉
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.\{0,9\}://' # 功能和前面一样,去掉:前的若干个字符,最多9个
/sbin/ifconfig eth0 |grep 'inet '| sed 's/.inet...://g'| sed 's/.....:.*$//g' # 将IP地址后的部分也去掉,.*表示无限个任意字符
awk是一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
使用方法
awk '{pattern + action}' {filenames}
其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号{}不需要在程序中始终出现,但它们用于根据特定的模式对一系列指令进行分组。 pattern就是要表示的正则表达式,用两个斜杠/括起来。
case1
last -n 5 # 取出登录数据前5行
# 结果如下
root pts/1 192.168.1.100 Tue Feb 10 11:21 still logged in
root pts/1 192.168.1.100 Tue Feb 10 00:46 - 02:28 (01:41)
root pts/1 192.168.1.100 Mon Feb 9 11:41 - 18:30 (06:48)
dmtsai pts/1 192.168.1.100 Mon Feb 9 11:41 - 11:41 (00:00)
root tty1 Fri Sep 5 14:09 - 14:10 (00:01)
last -n 5 | awk '{print $1}' # 显示最近登录的5个帐号,$1代表用空格或TAB隔开的第一个字段,以此类推,此句表示取每一行的第一个字段
# 结果如下
root
root
root
dmtsai
root
case2
cat /etc/passwd |awk -F ':' '{print $1}' # 功能类似,使用了-F ':'指定分隔符为冒号
# 结果如下
root
daemon
bin
sys
cat /etc/passwd |awk -F ':' '{print $1"\t"$7}' # 显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割
# 结果如下
root /bin/bash
daemon /bin/sh
bin /bin/sh
sys /bin/sh
case3
awk -F: '/root/' /etc/passwd # 搜索/etc/passwd有root关键字的所有行
# 结果如下
root:x:0:0:root:/root:/bin/bash
这种是pattern的使用示例,匹配了pattern(这里是root)的行才会执行action(没有指定action,默认输出每行的内容)。
搜索支持正则,例如找root开头的: awk -F: ‘/^root/’ /etc/passwd
awk -F: '/root/{print $7}' /etc/passwd # 搜索/etc/passwd有root关键字的所有行,并显示对应的shell
# 结果如下
/bin/bash
这里指定了action{print $7}
awk内置变量
awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。
ARGC 命令行参数个数
ARGV 命令行参数排列
ENVIRON 支持队列中系统环境变量的使用
FILENAME awk浏览的文件名
FNR 浏览文件的记录数
FS 设置输入域分隔符,等价于命令行 -F选项
NF 浏览记录的域的个数(每一行字段个数)
NR 已读的记录数(行号)
OFS 输出域分隔符
ORS 输出记录分隔符
RS 控制记录分隔符
举一个例子
# 统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容($0是代指整行)
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
egrep
正规表达方法
grep -v '^$' regular_express.txt |grep -v '^#' # 先去除空行,再去除注释行
需要用到管道线,grep搜寻了两次,如果使用延伸型的正则表达式,则可以简化为
egrep -v '^$|^#' regular_express.txt # 相当于或操作
grep 默认仅支持基础正则表达式,如果要使用扩展性正则表达式,可以使用 grep - E。grep -E 与 egrep 相当于命令别名关系。
常用扩展规则
加号+表示重复一个或一个以上的前一个 RE 字符
egrep -n 'go+d' regular_express.txt # gd之间,o至少重复两次
grep -n 'goo*d' regular_express.txt # 普通写法
问号?表示重复重复**零个或一个前一个**RE字符
egrep -n 'go?d' regular_express.txt # 仅搜索good或god
分隔符|表示用或的方式找出数个字符串
egrep -n 'gd|good' regular_express.txt
括号()表示找出群组字符串
egrep -n 'g(la|oo)d' regular_express.txt # 搜索good或glad
括号加号{}+表示多个重复群组判别
# 找开头是A结尾是C,中间有一个以上的 ‘xyz’ 或 ‘xz’ 字符串
echo 'AxyzxyzxyzxyzC'|egrep 'A(xyz)+C' # 可以匹配
echo 'AxyzxyzxyzxyzC'|egrep 'A(xz)+C' # 无法匹配