linux文本处理三剑客之一:grep

  • grep:文本过滤(模式:pattrn)工具
    • grep,egrep, fgrep(不支持正则表达式搜索)
  • sed:stream edittor 文本编辑工具
  • awk:linux上的实现gawk,文本报告生成器

1. grep

grep :Global search REguar expression and Print out the line
	作用:文本搜索工具,根据用户指定的"模式"对目标文本逐行进行匹配检查;打印匹配到的行
	模式:有正则表达式字符及文本字符所编写的过滤条件
grep [OPTIONS] PATTERN[FILE...]
	grep root /etc/passwd
	grep "$USER" /etc/passwd 
	grep '$USER' /etc/passwd
	grep '$UESR' /etc/passwd 
	grep `whoami` /etc/passwd
1.2 grep 命令选项
	--color=auto:对匹配的文本着色显示
	-v:显示不被pattern匹配到的行
	-i:忽略字符大小写
	-n:显示匹配的行号
	-c:统计匹配到的字符串
	-o:仅显示匹配到的字符串
	-q:静默模式,不输出任何信息
	-A n:after,后n行
	-B n:before,前n行
	-C n:context,前后各n行
	-e:实现多个选项间的逻辑or关系
		grep -e 'cat' -e 'dog' file
	-w:匹配整个单词   数字,字母,下划线算字母
	-E:使用ERE
	-F:相当于fgrep,不支持正则表达式 
	-f file:根据模式文件处理

2. 正则表达式

REGEXP:Regular Expressions 由一类特殊字符及文本字符所编写的模式,
		其中有一些字符(元字符)不表示字符字面意义,而表示控制或通配的功能
程序支持:grep sed awk vim less nginx,varnish等
分两类:
		基本正则表达式:BRE
		扩展正则表达式:ERE
				grep -E,egrep 
正则表达引擎:
	采用不同算法,检查处理正则表达式的软件模块
	PCRE(Perl Compatible Reguar Expressions)
元字符分类:字符匹配、匹配次数、位置锚定、分组
man 7 regex
2.1 基本正则表达式元字符:字符匹配
字符匹配:
	.  匹配任意单个字符
	[] 匹配指定范围内的任意单个字符,示例:[0-9][a-z][a-zA-Z]
	[^]匹配指定范围外的任意单个字符
	[:alnum:]字母和数字
	[:alpha:]代表任意英文大小写字符,亦即A-Z,a-z
	[:lower:]小写字母
	[:upper:]大写字母
	[:blank:]空白字符(空格和制表符)
	[:space:]水平和垂直的空白字符(比[:blabk:]包含的范围广)
	[:cntrl:]不可打印的控制字符(退格、删除、警铃...)
	[:digit:]十进制数字
	[:xdigit:]十六进制数字
	[:graph:]可打印的非空白字符
	[:print:]可打印字符
	[:punct:]标点符号
2.2 正则表达式:匹配次数
匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数
	
	*	    匹配前面的字符任意,包括0次
			    贪婪模式:尽可能长的匹配
	.*	    任意长度的任意字符
	\?	    匹配其前面的字符0或1次
	\+	    匹配其前面的字符至少1次
	\{n\}   匹配前面的字符n次
	\{m,n\} 匹配前面的字符至少m次,至多n次
	\{,n\}  匹配前面的字符至多n次
	\{n,\}  匹配前面的字符至少n次
例:
    . 表示任意的一个字符
    .* 表示任意长度 字符
    [.*?] 表示 . * ? 中的某一个
    [^] 排除
    [[:lower:]] 表示任意一个小写字母
    a* 表示前面的字符出现任意次
    [[:lower:]]*  表示出现一次或多次小写字符
    a\? 表示a出现0次或一次  (可有可无)
    a\+ 表示a出现一次以上
    a\{10\} 表示a出现10次
    a\{10,20\}表示a出现10到20次
    a\{,20\}表示a出现20次以下
    a\{10,\}表示a出现10次以上
    a|bcd 表示a或bcd
    (a|b)cd 表示acd或bcd
    
    找出/etc/passwd中以bash和nologin结尾的行
    egrep "(bash|nologin)$" /etc/passwd
2.3正则表达式:位置锚定
位置锚定:定位出现的位置
	^行首锚定,用于模式的最左侧
	$行尾锚定,用于模式的最右侧
	^PATTERN$用于模式匹配整行
		^$ 空行
		^[[:space:]]*$空白行
	\<或\b词首锚定,用于单词模式的左侧
	\>或\b词尾锚定,用于单词模式的右侧
	\<PATTERN\>匹配整个单词
2.4 正则表达式:分组
分组:\(\)将一个或多个字符捆绑在一起,当做一个整体,如:\(root\)+
分组括号中的模式匹配到内容的内容会被正则表达式引擎记录与内部的变量中,这些变量的命名方式为:\1,\2,\3,...
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例:  \(string1\+\(string2\)*\)  嵌套
		\1:string1\+\(string2\)*
		\2:string2 

例:
grep "\(hello\)\{2,\}"
%s/r\(..\)t/\1/g
%s/\(r..t\)/\1er/g
2.5正则表达式:后向引用
后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
或者:\|
示例:a\|b        a或b 
      C\|cat      C或cat
	  \(C|\c\)at  Cat或cat

grep -v "^$\|^#" /etc/file 

3. egrep 及扩展的正则表达式

  • egrep = grep -E
  • egrep [OPTIONS] PATTERN [FILE...]
  • 扩展正则表达式的元字符:
3.1字符匹配:
    .任意单个字符
	[]指定范围的字符
	[^]不在指定范围的字符
3.2次数匹配:
	* 匹配前面字符任意次
	? 0或1次
	+ 1次或多次
	{m} 匹配m次
	{m,n} 至少m,至多n次
3.3位置锚定:
	^  行首 
	$  行尾
	\<,\b 语首
	\>,\b 语尾
3.4分组:
	()
	后向引用:\1,\2,...
3.5 或者:
	a|b      a或者b
	C|cat    C或者cat
    (C|c)at  Cat或者cat

练习:



利用df和grep,取出磁盘各分区利用率,并从大到小排序
df |grep "^/dev/sd"|egrep -o '[[:digit:]]+%'|tr -d % |sort -nr

找出/etc/passwd用户名和shell同名的行
egrep "^([^:]+):.*\<\1$" /etc/passwd
egrep  -o "^(.*)(:.*)\<\1$"  /etc/passwd


取出ifconfig eth0的ip
ifconfig ens33 | egrep -o "([0-9]{1,3}.){3}[0-9]{1,3}"

取出ss.log日志中排名前三的ip地址
grep "^ESTAB" ss.log | tr -s ' ' :| cut -d: -f6|sort|uniq -c|sort -nr |head -3

将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前⾯
echo wecome to magedu linux | grep -o "."|sort|uniq -c |sort -nr

使⽤egrep取出/etc/rc.d/init.d/functions路径的⽬录名
echo /etc/rc.d/init.d/functions|egrep -o "^[/].*/"

计算年龄总和:
cat age.txt
xiaoming=20
xiaohong=18
xiaoqiang=22

cut -d= -f2 age.txt |tr -s "\n" +|egrep -o ".*[0-9]+" |bc
60