六、grep与正则表达式 (文本过滤)
一、正则表达式
正则表达式:Regual Expression, REGEXP。
由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能;
基本正则表达式:BRE
扩展正则表达式:ERE
1.基本正则表达式的元字符
1.1 字符匹配:
. :匹配任意单个字符 []:匹配指定范围内的任意单个字符 [^]:匹配指定范围外的任意单个字符 [:digit:] 数字 [:lower:] 小写字母 [:upper:] 大写字母 [:alpha:] 字母 [:alnum:] 数字 [:punct:] 标点符号 [:space:] 垂直或水平的空白字符
1.2 匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数;
*:匹配前面的字符任意次,包括0次;默认工作在贪婪模式(尽可能长的匹配) .:任意单个字符 .*:任意长度的任意字符 ?:匹配前面的字符0次或1次 \+:匹配前面的字符至少1次 \{n\}:匹配前面的字符n次 \{n,m\}:匹配前面的字符n至m次 \{n,\}:匹配前面的字符至少n次 \{,m\}:匹配前面的字符至多m次
1.3 位置锚定:定位要锚定的字符出现的位置
- ^(脱字符):行首锚定,用于匹配模式的最左侧
- $:行尾锚定,用于匹配模式的最右侧
- ^$:空行
- ^[[:space:]]$:空白行(空行或含有空白字符的行)
- ^PATTERN$:用于PATTERN来匹配整行
- \< 或\b 词首锚定,用于单词模式的左侧
- \> 或\b 词尾锚定,用于单词模式的右侧
- \bPATTERN\b 或<PATTERN> 匹配整个单词
注意:非特殊字符组成的连续字符(字符串)都称为单词;
1.4 分组及引用:\(\) 将一个或多个字符捆绑在一起,当做一个整体进行处理;如\(root\)\+,表示将root分为一组,且匹配至少1次
后向引用:引用前面的分组括号中的模式所匹配字符(而非模式本身)
注:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3
\1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符;
\2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符;
\3:
示例:\(string1\+\(string2\)\)
\1:(string1+(string2))
\2:(string2)
\(ab\+\(xy\)*\)
\1:ab\+\(xy\)*
\2:xy
二、grep、egrep、fgrep(不支持正则表达式)
grep:Global search REgular expression and Print out the line.
作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查;打印匹配到的行;
模式:由正则表达式字符及文本字符所编写的过滤条件
grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] # option: --color=auto:对匹配到的文本着色后高亮显示; -i:ignorecase,忽略字符的大小写; -o:仅显示匹配到的字符串本身; -w:显示匹配到的整个单词 -v, --invert-match:反向选择(显示不能被模式匹配到的行); -e:实现多个选项间的逻辑or关系 -n:显示匹配的行号 -c: 统计匹配的行数 -E:支持使用扩展的正则表达式元字符; -q, --quiet, --silent:静默模式,即不输出任何信息; -A 5:after, 后5行 -B 5:before,前5行 -C 5:context,前后各5行
扩展匹配:egrep=grep -E
字符匹配
.
[]
[^]
次数匹配
*:匹配前面的字符任意次,包括0次;默认工作在贪婪模式(尽可能长的匹配) .:任意单个字符 .*:任意长度的任意字符 ?:匹配前面的字符0次或1次 +:匹配前面的字符至少1次 {n}:匹配前面的字符n次 {n,m}:匹配前面的字符n至m次
锚定:
^
$
\>,\b
\<,\b
分组:
() 注不需要转义
后向引用:\1,\2,...
或者:|
示例: a|b :a或b C | cat:C或cat (C|c)at:Cat或cat
1、显示/etc/passwd文件中不以/bin/bash结尾的行;
grep -v "/bin/bash$" /etc/passwd
2、找出/etc/passwd文件中的两位数或三位数;
grep "\<[0-9]\{2,3\}\>" /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:]]*$"
1、找出/proc/meminfo文件中,所有以大写或小写S开头的行;至少有三种实现方式;
- grep -i "^s" /proc/meminfo
- grep "^[sS]" /proc/meminfo
- grep -E "^(s|S)" /proc/meminfo
2、显示当前系统上root、centos或user1用户的相关信息;
grep -E "^(root|centos|user1)\>" /etc/passwd | cut -d: -f1,3,7
显示/etc/passwd文件中ID号最大的用户的用户名
sort -t: -k3 -n /etc/passwd | tail -1 |cut -d: -f1
如果用户root存在,显示其默认的shell程序
id root &> /dev/null && grep "^root\>" /etc/passwd |cut -d: -f7
3、找出/etc/rc.d/init.d/functions文件中某单词后面跟一个小括号的行;
grep -E -o "[_[:alpha:]]+\(\)" /etc/rc.d/init.d/functions
4、使用echo命令输出一绝对路径,使用egrep取出基名;
echo /etc/sysconfig/ | grep -E -o "[^/]+/?$" | cut -d "/" -f1
进一步:取出其路径名;类似于对其执行dirname命令的结果;
echo /etc/sysconfig/ | grep -E -o "^[/]+[[:alpha:]]*"
5、找出ifconfig命令结果中的1-255之间的数值;
ifconfig | grep -E -o "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
6、课外作业:找出ifconfig命令结果中的IP地址;
ifconfig | egrep -o "([0-9]{1,3}.){3}[0-9]{1,3}" --color=auto
7、添加用户bash, testbash, basher以及nologin(其shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名的行;
grep -E "^\([[:alnum:]]+\>\).*\1$" /etc/passwd
grep -E "^\([^:]+\>\).*\1$" /etc/passwd