此为Sunny 王苗苗同学的学习笔记,持续学习,持续分享,持续进步,向着大神之路前进~
本文主要内容:grep及基本正则表达式
grep,egrep,fgrep:文本过滤工具,根据模式(pattern)过滤
grep:基本正则表达式
egrep:扩展正则表达式
fgrep:不支持正则表达式
sed:stream editor,流编辑器,文本编辑工具
awk:linux上的实现为gawk,文本报告生成器,主要就是格式化文本
作用:文本搜索工具,根据用户指定的“模式(过滤条件)”对目标文本逐行进行匹配检查,打印匹配到的行。
模式(过滤条件):由正则表达式的元字符及文本字符所编写的过滤条件。
grep [OPTIONS] PATTERN [FILE...]
OPTIONS:
--color=auto:对匹配到的文本着色后高亮显示
-i:ignorecase,忽略字符的大小写
-o:仅显示匹配到的字符集本身
-v:--invert-match,显示不能被模式匹配到的行
-E:支持使用扩展的正则表达式元字符
-q:--quiet,--silent:静默模式,即不输出任何信息,多用于脚本编程,只关注命令执行状态而不是结果
-A #:after,后#行
-B #:before,前#行
-C #:context,前后#行
#使用alias查看别名,可以看到grep 是grep --color=auto的别名,所以grep找到的结果默认就会高亮显示
[root@redhat Desktop]# alias
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
#找到一个文档,准备来做实验
[root@redhat Desktop]# cat vsftpd.conf
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
#grep是严格区分大小写的,使用yes可以看到没有匹配的
[root@redhat Desktop]# grep "yes" vsftpd.conf
#但是使用-i选项可以忽略大小写,这样YES就会被找出来
[root@redhat Desktop]# grep -i "yes" vsftpd.conf
anonymous_enable=YES
local_enable=YES
write_enable=YES
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen_ipv6=YES
userlist_enable=YES
tcp_wrappers=YES
#-o 表示只打印出匹配到的字符,这里找YES,所以打印出来的只有YES
[root@redhat Desktop]# grep -o "YES" vsftpd.conf
YES
YES
YES
YES
YES
YES
YES
YES
YES
YES
#-v代表打印出没有匹配到的行,从结果可以看到,打印的是不包含YES的行
[root@redhat Desktop]# grep -v "YES" vsftpd.conf
local_umask=022
listen=NO
pam_service_name=vsftpd
#使用静默模式,可以看到没有输出信息
[root@redhat Desktop]# grep -q "YES" vsftpd.conf
#再使用echo $?可以查看上一条命令的执行状态,0代表成功,也就是上一条有匹配到
[root@redhat Desktop]# echo $?
0
#这个可以用来查是否有该用户,存在则XX,如下查sunny用户是否存在
[root@redhat Desktop]# grep "sunny" /etc/passwd
sunny:x:1000:1000:sunny:/home/sunny:/bin/bash
#有找到,说明存在
[root@redhat Desktop]# echo $?
0
#查zhangsan是否存在,运行失败,即不存在
[root@redhat Desktop]# grep "zhangsan" /etc/passwd
[root@redhat Desktop]# echo $?
1
#-A 2,除匹配到的行外,多显示后两行,这个在查找日志时应该十分有用
[root@redhat Desktop]# grep -A 2 "port" vsftpd.conf
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
# -B 2,除匹配到的行外,多显示前两行,这个在查找日志时应该十分有用
[root@redhat Desktop]# grep -B 2 "port" vsftpd.conf
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
# -C 2,除匹配到的行外,多显示前后两行,这个在查找日志时应该十分有用,例如找某个异常的前后10行等
[root@redhat Desktop]# grep -C 2 "port" vsftpd.conf
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
模式(过滤条件)除了使用文本外还可以使用正则表达式
接下来介绍基本的正则表达式有哪些。
基本正则表达式元字符,主要可以分为3类,分别为匹配字符、匹配次数、匹配位置、分组及引用
也就是你要匹配的字符内容是什么
.:匹配任意单个字符
[]:匹配指定范围内的任意单个字符
[^]:匹配指定范围外的任意单个字符
其他一些特殊格式的在globbing中已经提到过,点此查看globbing
数字[:digit:],小写字母[:lower:],大写字母[:upper:],字母[:alpha:],字母加数字[:alnum:],所有符号[:punct:],所有空格[:space:]
#匹配r和t之间有任何两个字符的行
[root@redhat Desktop]# grep "r..t" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
#匹配r和t之间有任意两个字母的,这样之前匹配到的r/ft这行就被过滤掉了
[root@redhat Desktop]# grep "r[[:alpha:]][[:alpha:]]t" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
#匹配所有的非字母和数字,其实也就是匹配符号
[root@redhat Desktop]# grep "[^[:alnum:]]" vsftpd.conf
anonymous_enable=YES
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=NO
listen_ipv6=YES
pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
用在要指定其出现次数的字符后面,用于限制其前面字符出现的次数
好记一点,次数匹配就是用{},只是需要加转义字符\
*:匹配其前面字符任意次,也就是0,1,或多次
.*:匹配任意长度的任意次
\?:匹配其前面字符0次或者一次,即前面字符是可有可无的
\+:匹配其前面字符1次或多次,即前面字符至少出现一次
\{m\}:匹配其前面字符m次
\{m,n\}:匹配其前面字符至少m次,至多n次
\{0,n\} :至多n次
\{m,\} :至少m次
也就是限定字符要出现在哪个位置。想想看位置一般会有哪些呢?行首、行中、行尾、词首、词中、词尾
什么叫单词?单词:非特殊字符组成的连续字符(字符集)都称为单词
^:行首锚定,用于模式的最左侧
$:行尾锚定,用于模式的最右侧
^PATTERN$:用于PATTERN来匹配整行
\<或\b:词首锚定,用于单词模式的左侧
\>或\b:词尾锚定,用于单词模式的右侧
\:匹配完整的单词
练习:
1、显示/etc/passwd文件中不以/bin/bash结尾的行;
grep -v "/bin/bash$" /etc/passwd
2、找出/etc/passwd文件中的两位数或三位数;
grep "\<[0-9]\{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:模式从左侧起,第一个左括号 以及 与之匹配的右括号之间 的模式所匹配到的字符
\2:模式从左侧起,第二个左括号 以及 与之匹配的右括号之间 的模式所匹配到的字符
\3:...
...
后向引用:引用前面的分组括号中的模式匹配到的字符
练习:
1、新建文件,写入如下内容
He loves his lover.
He likes his lover.
She likes her liker.
She loves her liker.
找出前面出现过,后面又出现一次的行,也就是love/like前面出现了,后面又出现了了的行
grep "\(l..e\).*\1" love