正则表达式和grep
1)字符匹配
. 匹配任意单个字符
[] 匹配指定范围内的任意单个字符,示例:[long] [0-9] [a-z] [a-zA-Z],注意中括号里面的一定是一个字符
[^] 匹配指定范围外的任意单个字符,示例:[^long]
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,即:a-z,A-Z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格,删除,警铃...)
[:digit:] 十进制数字
[:xdigit:] 十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
2)匹配次数
* 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* 任意长度的任意字符
? 匹配其前面的字符0或1次,即:可有可无
+ 匹配其前面的字符至少1次,即:肯定有
{n} 匹配前面的字符n次
{m,n} 匹配前面的字符至少m次,至多n次
{,n} 匹配前面的字符至多n次
{n,} 匹配前面的字符至少n次
3)位置锚定
^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
< 或 词首锚定,用于单词模式的左侧
> 或 词尾锚定,用于单词模式的右侧
<PATTERN> 匹配整个单词
4)分组其他
分组:()将一个或多个字符捆绑在一起,当作一个整体处理,如:(root)+
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:1,2,3...
1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例:
(string1(string2))
1 :string1(string2)
2 :string2
向后引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
或者:\|
a|b # a或b
C|cat # C或cat
(C|c)at # Cat或cat
5)范例练习
1,显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法实现)
#方法1
grep -i ^s /proc/meminfo
#方法2
grep -i ^[S|s] /proc/meminfo
2,显示/etc/passwd文件中不以/bin/bash结尾的行
grep -Ev "/bin/bash" /etc/passwd
3,找出/etc/passwd中的两位或三位数
grep -E "<[[:digit:]]{2,3}>" /etc/passwd
4,显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行
grep "^[[:space:]].*[[:space:]].*" /etc/grub2.cfg
5,找出“netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行
netstat -tan | grep LISTEN
6,显示CentOS7上所有UID小于1000以内的用户名和UID
grep "<[0-9]{1,3}>" /etc/passwd
7,利用df和grep,取出磁盘各分区利用率,并从大到小排序
df -h | grep dev/sd.* | tr -s ' ' %|cut -d% -f5 |sort -nr
# 扩展表达元字符
1)字符匹配
. 任意单个字符
[long] 指定范围的字符
[^long] 不在指定范围的字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,即:A-Z ,a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符 (比如:[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格,删除,警铃...)
[:digit:] 十进制数字
[:xdigit:] 十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
2)匹配次数
* 匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配 n次
{m,n} 至少m,至多 n次
3)位置锚定
^ 行首
$ 行尾
<, 词首
>, 词尾
4)分组
() 分组
向后引用:1,2,...
| 或者
a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat
5)范例练习
1,显示三个用户root,long,wang的UID和默认的shell
cat /etc/passwd | egrep -e "^root" -e '^long' -e '^wang' | cut -d: -f1,3,7
2,找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
grep -e "^<.*>()" /etc/rc.d/init.d/functions
3,使用egrep取出/etc/rc.d/init.d/functions中其基名
echo "/etc/rc.d/init.d/functions" | egrep -o "<[^/]+/?$"
4,使用egrep取出/etc/rc.d/init.d/functions的目录名
echo "/etc/rc.d/init.d/functions" egrep -o "(^/([^/]+/)*)"
5,统计last命令中以root登录的每个主机IP地址登录次数
last | grep -e root | tr -s " " | cut -d ' ' -f1,3 | sort | uniq -c
6,显示ifconfig命令结果中所有IPv4地址
ifconfig | grep -o '([0-9]{1,3}.){3}[0-9]{1,3}' | sort | head -n3
##面试题范例
1,使用egrep取出字符串“/etc/rc.d/init.d/functions”路径的目录名
echo "/etc/rc.d/init.d/functions" | egrep -o '^/.*/'
2,统计字符串 "welcome to magedu linux !" 中每个字母出现的次数并从大到小排序
echo "welcome to magedu linux" | egrep -o [a-z] | sort | uniq -c
3,请使用 grep 命令统计 /etc/fstab 文件中每个单词出现的次数?
cat /etc/fstab | grep -o '<[a-z]+>' | sort | uniq -c
4,使用 grep 命令找出 ip a 命令输出信息中的所有 IPv4 地址
ip a | grep -o '([0-9]{1,3}.){3}[0-9]{1,3}'
5,找出 /etc/passwd 文件中用户名和 shell 同名的行
cat /etc/passwd | grep '^([a-z]+):.*1$'
6,找出 /etc/rc.d/init.d/functions 文件中所有的函数名称,名称包含 _ 和 ()
grep -o '[^ ]+()' /etc/rc.d/init.d/functions
7,如何在 vim 中设置 tab 的长度为四个空格?
echo "set ts=4" >> /etc/vimrc
8,拷贝 /etc/rc.d/init.d/functions 文件到 /tmp 中,文件通常使用 '#' 作为注释的开始,请你使用 vim 的搜索替换功能打卡所有的注释
命令模式输入 :%s@^#([[:space:]]+.*)@1@g
9,请使用 grep 命令统计 /etc/fstab 文件中每个单词出现的次数?
grep -o '<[[:alpha:]]+>' /etc/fstab | sort|uniq -c
# grep的用法 #
格式:grep [OPTIONS] PATTERN [FILE...]
常见选项:
--color=auto 对匹配到的文本着色显示
-m # 匹配 # 次后停止
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息。 #其实是执行了grep的匹配,然后将匹配的结果重定向到了/dev/null中
-A # after,后 # 行
-B # before,前 # 行
-C # context,前后各 # 行
-e 实现多个选项间的逻辑or关系,如:grep -e 'root' -e 'bin' file
-w 匹配整个单词
-E 使用ERE,相当于 egrep
-F 不支持正则表达式,相当于fgrep
# -f file 根据模式文件处理
-r 递归目录,但不处理软链接
-R 递归目录,但处理软链接
1,grep支持匹配命令和变量
grep $USER /etc/passwd
grep `whoami` /etc/passwd
2,-f FILE根据文件内容进行匹配。可以提前将要匹配的内容放在文本中
#梳理(整理)归纳
'[0-9]?[0-9]' #0-100
3,典型用法:去掉某个配置文件中以#开头的行和空行。##理解,以#开头和空行是逻辑或的关系
方法1,比较低端写法
cat /etc/fstab | grep -v ^# | grep -v ^$
方法2
cat /etc/fstab | grep -v -e '^#' -e '^$'
方法3 比较好
cat /etc/fstab | grep -v '^#|^$'
方法4 牛逼方法
cat /etc/fstab | grep ^[^#]
4,grep取出基名
echo "/etc/rc.d/init.d/functions" | egrep -o '[^/]+/?$'
5,grep取出目录名
echo "/etc/rc.d/init.d/functions" | egrep -o '/.*[^/]' | egrep -o '/.*/' | egrep -o '.*[^/]'
6,正规ip地址的表示方法
0-99|100-199|200-249|250-255
egrep -o "^(([0-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]).){3}([0-9]?[0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"
#注意要点:
#1、要加^$限定范围;
#2、左边两个小括号,分别将ip地址的x和x.作为一个整体
#3、最后一位数的那个小括号其实加不加无所谓