Linux入门真经-026grep与基本正则表达式
Linux中盛传着著名的文本处理三剑客:grep(基于正则表达式的文本过滤器)、sed(行编辑器)、awk(文本排版格式化工具)。
今天我们要介绍的就是grep,可以帮助我们根据关键字或者正则表达式过滤文本,便于我们更好地获取信息。
1、正则表达式概述
正则表达式是由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是表示控制或通配的功能。(我们称之为元字符)
正则表达式可以分为两类:基本正则表达式和扩展正则表达式。
其中,基本正则表达式具有较高的匹配效率,但是表达式相对晦涩一些。
扩展正则表达式更加易懂,但是就效率而言,稍逊于基本正则表达式
2、grep:基于基本正则表达式的文本搜索工具
grep是一个文本搜索工具,根据用户指定的模式(过滤条件,pattern。由正则表达式编写),对目标文本文件进行逐行匹配(敲黑板:逐行匹配)检查。遍历文本后打印匹配到的行。
grep还有两个分支:egrep(支持扩展的正则表达式)和fgrep(不支持正则表达式)。
本节介绍grep基本正则,下一节介绍egrep和扩展正则。fgrep不作介绍,因为grep的功能早已盖过了它。
grep [OPTIONS] PATTERN [FILE...]
OPTIONS:
--color=auto:对匹配到的文本着色后高亮显示;默认执行的grep命令其实是别名grep --color=auto
-i:ignorecase,忽略字符的大小写;
-o:仅显示匹配到的字符串本身;
-v,--invert-match:显示不能被模式匹配到的行;
-E:支持使用扩展的正则表达式元字符;等价于egrep
-q,--quiet, --silent:静默模式,即不输出任何信息;
-A#:after, 后#行
-B#:before,前#行
-C#:context,前后各#行
举例:查看与grep相关的别名(从alias输出中过滤grep关键字)
[[email protected] ~]# alias | grep grep
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
查看匹配到的前1行和后2行
[[email protected] ~]# alias | grep -B1 -A2 grep
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'
[[email protected] ~]#
3、基本正则表达式
接下来,先讲正则表达式的法则,再做练习。
基本正则表达式元字符:
字符匹配相关:
.:匹配任意单个字符;
[]:匹配指定范围内的任意单个字符;
[^]:匹配指定范围外的任意单个字符;
[:digit:]:数字;
[:lower:]:小写字母
[:upper:]:大写字母:
[:alpha:]:字母;
[:alnum:]:字母和数字;
[:punct:]:符号
[:space:]:空格
匹配次数:用在要指定其出现的次数的字符的后面,用于限制其前面字符出现的次数;默认工作于贪婪模式(能多匹配就多匹配);
*:匹配其前面的字符任意次;0,1,多次;
.*:匹配任意长度的任意字符
\?:匹配其前面的字符0次或1次;即其前面的字符是可有可无的;
\+:匹配其前面的字符1次或多次;即其面的字符要出现至少1次;
\{m\}:匹配其前面的字符m次;
\{m,n\}:匹配其前面的字符至少m次,至多n次;
\{0,n\}:至多n次
\{m,\}:至少m次
举例:
首先先创建一个供我们测试的文件(我用的是IO重定向的方法,你也可以使用vi去做)
[[email protected] ~]# touch /tmp/test_grep
[[email protected] ~]# echo -e"xy2\nxy12\nxxxxxxxxxxxxxxxxxxxxyyyy122\n2xy" > /tmp/test_grep
[[email protected] ~]# cat !$
cat /tmp/test_grep
xy2
xy12
xxxxxxxxxxxxxxxxxxxxyyyy122
2xy
匹配至少连续出现两次x的行
[[email protected] ~]# cat /tmp/test_grep |grep "x\{2,\}"
xxxxxxxxxxxxxxxxxxxxyyyy122
匹配y后面全接数字的行
[[email protected] ~]# cat /tmp/test_grep |grep "y[[:digit:]]\+"
xy2
xy12
xxxxxxxxxxxxxxxxxxxxyyyy122
位置锚定元字符:
^:行首锚定;用于模式的最左侧;
$:行尾锚定;用于模式的最右侧;
^PATTERN$:用于PATTERN来匹配整行;
^$:空白行;
^[[:space:]]*$:空行或包含空白字符的行;
单词:非特殊字符组成的连续字符(字符串)都称为单词;
\< 或 \b:词首锚定,用于单词模式的左侧;
\> 或 \b:词尾锚定,用于单词模式的右侧;
\<PATTERN\>:匹配完整单词;
练习:
显示/etc/passwd文件中以bash结尾的行;
[[email protected] ~]# grep "bash$" /etc/passwd
root:x:0:0:root:/root:/bin/bash
sunny:x:1000:1000:sunny:/home/sunny:/bin/bash
centostest:x:4002:5002::/home/centostest:/bin/bash
test:x:4003:4003::/home/test:/bin/bash
找出/etc/passwd文件中包含两位数或三位数的行;
[[email protected] ~]# grep"\<[0-9]\{2,3\}\>" /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd NetworkManagement:/:/sbin/nologin
dbus:x:81:81:System messagebus:/:/sbin/nologin
polkitd:x:999:998:User forpolkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separatedSSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
[[email protected] ~]#
找出/etc/sudoers中的非空白行和非注释行(#开头的行表示注释)
[[email protected] ~]# cat /etc/sudoers | grep-v "^$" | grep -v "^#"
Defaults !visiblepw
Defaults always_set_home
Defaults match_group_by_gid
Defaults env_reset
Defaults env_keep = "COLORS DISPLAYHOSTNAME HISTSIZE KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESSLC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPERLC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSETXAUTHORITY"
Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
rootALL=(ALL) ALL
test ALL=(ALL) ALL
%wheel ALL=(ALL)ALL
分组及引用相关的元字符:
\(\):将一个或多个字符捆绑在一起,当作一个整体进行处理;
Note:分组括号中的模式匹配 到的内容会被正则表达式引擎自动记录于内部的变量中,这些变量为:
\1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符;
\2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符;
\3:。。。。。。。。三。。。。
…
\n
举例:
创建一个文本文件chicken_kitchen,内容如下:
chicken is chicken
kitchen is kitchen
chicken is not kitchen
kitchen is not chicken
匹配出现了两次chicken的行
[[email protected] ~]# cat chicken_kitchen |grep "\(chicken\).*\1"
chicken is chicken
[[email protected] ~]#
下一节我们介绍扩展正则表达式