Linux之文本处理三剑客介绍
sed sream eidtor 行编辑器,也能实现文本过滤功能
grep
通配原理:grep程序依据,用户给出的模式对标准输入输入的数据流逐个匹配检测,并将匹配到的字符串以行的方式显示到标准输出
模式:PATTERN,由正则表达式字符或纯文本字符所编写的过滤条件,注意纯文本字符用grep匹配也会调用正则表达式引擎,不如直接用fgrep
正则表达式字符:Regular Expression,简写regex,regexp,RE表示,由不表示字面意义的特殊字符表示,有“基本正则表达式字符”“扩展正则表达式字符”
与grep相关的工具:
grep,支持基本正则表达式 BRE,Basic Regular Expression
egrep,支持扩展正则表达式 ERE,Extension Regular Expression
fgrep,不支持正则表达式 FRE Fast Regular Expression ,最为高效的精确匹配算法实现字符匹配
能够调用正则表达式的工具:
grep,egrep,sed,awk,perl
1)正则表达式的元字符不同
2)各自调用不同的正则表达式引擎
3)各自实现的算法不一样
4)perl支持较为强大的正则表达式引擎,一般写程序需要用到正则表达式,都会调用perl的正则表达式,如果需要使用perl的正则表达式,需要在编译时指明 --pcre,就能实现正则表达式解析和匹配检查。
正则表达式引擎:把模式套到文本,检查表达式匹配与否
grep命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<code>1、第一步,获取命令的类型</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># type grep </code>
<code>grep</code> <code>is aliased to `</code><code>grep</code> <code>--color=auto'</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># which --skip-alias grep</code>
<code>/usr/bin/grep</code>
<code>2、用外部命令获取帮助的方法,获取</code><code>grep</code><code>命令的帮助</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># grep --help</code>
<code>Usage: </code><code>grep</code> <code>[OPTION]... PATTERN [FILE]...</code>
<code>通过模式搜索每一个文本或标准输入的数据,显示由PATTERN匹配到的字串所在的行。</code>
<code>默认使用BRE匹配</code>
<code>Regexp selection and interpretation:</code>
<code>-E, --extended-regexp </code><code>#ERE</code>
<code>-F, --fixed-strings </code><code>#FRE</code>
<code>-G, --basic-regexp </code><code>#BRE</code>
<code>-P, --perl-regexp </code><code>#PRE</code>
<code>-i, --ignore-</code><code>case</code> <code>#匹配时忽略PATTERN中字符大小写</code>
<code>Miscellaneous:</code>
<code> </code><code>-</code><code>v</code><code>, --invert-match </code><code>#仅显示不能够PATTERN匹配到的行</code>
<code> </code>
<code>Output control:</code>
<code>-n,--number </code><code>#显示匹配到的行的行号</code>
<code>-c, --count </code><code>#显示匹配到的行的行数</code>
<code>-o, --only-matching </code><code>#仅显示匹配到的字符串</code>
<code>-q, --quiet, --silent </code><code>#静默模式</code>
<code>Context control:</code>
<code>-B, --before-context=NUM </code><code>#显示匹配到的行及行前的NUM行</code>
<code>-A, --after-context=NUM </code><code>#显示匹配到的行及行后的NUM行</code>
<code>-C, --context=NUM </code><code>#显示匹配到的行及行前后各NUM行</code>
<code>--colour=auto </code><code>#将匹配到的文本高亮显示</code>
grep选项注释
--colour=auto #将匹配到的文本高亮显示
1、自动高亮显示文本
<a href="https://s4.51cto.com/wyfs02/M01/9D/5F/wKiom1l--daxjp0RAAAoMosaQaU262.png" target="_blank"></a>
2、Rehl7系统自动添加别名,Rehl 6需要定义‘grep别名’方能简化grep匹配时高亮显示的过程
<code>[root@izpo45bh60h6bsz ~]</code><code># alias</code>
<code>alias</code> <code>egrep</code><code>=</code><code>'egrep --color=auto'</code>
<code>alias</code> <code>fgrep</code><code>=</code><code>'fgrep --color=auto'</code>
<code>alias</code> <code>grep</code><code>=</code><code>'grep --color=auto'</code>
-v 不显示被PATTERN匹配到的字符串所在的行,只显示其他行
<code>[root@izpo45bh60h6bsz ~]</code><code># vim b.txt</code>
<code>a 1 b c</code>
<code>c 3 b c</code>
<code>d 10 c e</code>
<code>o 110 d f</code>
<code>l 2 f s</code>
<code>E 99 A D</code>
<code>A 77 D 1</code>
<code>SD 45 DF DF</code>
<code>MEI 66 AD OOO</code>
1、显示被PATTERN匹配到的字符串所在的行
<a href="https://s5.51cto.com/wyfs02/M00/9D/5F/wKioL1l_ADLwBCnsAAAHYPuXjKk101.png" target="_blank"></a>
2、显示模式不能匹配的行
<a href="https://s3.51cto.com/wyfs02/M02/9D/5F/wKiom1l_AJrwWus-AAAOYoHzgoc059.png" target="_blank"></a>
- q,quit 匹配到的内容不显示到标准输出,一般用于使用"命令的执行状态结果"
1、如果gentoo用户存在就显示OK
<code>[root@izpo45bh60h6bsz ~]</code><code># who | grep -q '^gentoo\b' && echo 'OK'</code>
*逻辑运算中:与运算:左侧为真,才会继续向后执行
-i 忽略PATTERN中特殊字符的大小写
<code>grep</code> <code>-i </code><code>'how'</code> <code>a.txt</code>
<a href="https://s2.51cto.com/wyfs02/M02/9D/5F/wKioL1l_A5mDt-dTAAAJxYqalio765.png" target="_blank"></a>
-C,context 显示匹配到的行及前后各NUM行
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -C 2 -i 'ipvs' /boot/config-3.10.0-514.6.2.el7.x86_64 </code>
<code>CONFIG_NETFILTER_XT_MATCH_HL=m</code>
<code>CONFIG_NETFILTER_XT_MATCH_IPRANGE=m</code>
<code>CONFIG_NETFILTER_XT_MATCH_IPVS=m</code>
<code>CONFIG_NETFILTER_XT_MATCH_LENGTH=m</code>
<code>CONFIG_NETFILTER_XT_MATCH_LIMIT=m</code>
-A,after 显示匹配到的行及后NUM行
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -A 2 'root' /etc/passwd</code>
<code>root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code>
<code>bin:x:1:1:bin:</code><code>/bin</code><code>:</code><code>/sbin/nologin</code>
<code>daemon:x:2:2:daemon:</code><code>/sbin</code><code>:</code><code>/sbin/nologin</code>
<code>....</code>
-B,before 显示匹配到的行及前NUM行
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -B 2 'root' /etc/passwd</code>
<code>root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code> <code>#此处为首行,之前没有,所以显示不出来</code>
<code>--</code>
<code>halt:x:7:0:halt:</code><code>/sbin</code><code>:</code><code>/sbin/halt</code>
<code>mail:x:8:12:mail:</code><code>/var/spool/mail</code><code>:</code><code>/sbin/nologin</code>
<code>operator:x:11:0:operator:</code><code>/root</code><code>:</code><code>/sbin/nologin</code>
-o,only-match 仅显示匹配到的字符串
<code># grep -o 'root' /etc/passwd</code>
<a href="https://s1.51cto.com/wyfs02/M01/9D/60/wKiom1l_BQ2Al4ZLAAAMBTEa8Pc038.png" target="_blank"></a>
-n,number 显示匹配到的行的行号
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -n 'root' /etc/passwd</code>
<code>1:root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code>
<code>10:operator:x:11:0:operator:</code><code>/root</code><code>:</code><code>/sbin/nologin</code>
<code>29:dockerroot:x:995:992:Docker User:</code><code>/var/lib/docker</code><code>:</code><code>/sbin/nologin</code>
<code>41:hello:x:1008:1008::</code><code>/root/hello</code><code>:</code><code>/bin/bash</code>
<code>42:hello1:x:1009:1009::</code><code>/root/hello</code><code>:</code><code>/bin/bash</code>
<code>43:hello2:x:1010:1010::</code><code>/root/hello</code><code>:</code><code>/bin/bash</code>
<code>47:vuser:x:994:990::</code><code>/var/ftproot</code><code>:</code><code>/bin/bash</code>
<code>48:gentoo:x:1016:1016::</code><code>/root/gentoo</code><code>:</code><code>/bin/bash</code>
<code>49:slackware:x:1017:1017::</code><code>/root/slackware</code><code>:</code><code>/bin/tcsh</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># awk '/root/{print NR,$0}' /etc/passwd</code>
<code>1 root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code>
<code>10 operator:x:11:0:operator:</code><code>/root</code><code>:</code><code>/sbin/nologin</code>
<code>29 dockerroot:x:995:992:Docker User:</code><code>/var/lib/docker</code><code>:</code><code>/sbin/nologin</code>
<code>41 hello:x:1008:1008::</code><code>/root/hello</code><code>:</code><code>/bin/bash</code>
<code>42 hello1:x:1009:1009::</code><code>/root/hello</code><code>:</code><code>/bin/bash</code>
<code>43 hello2:x:1010:1010::</code><code>/root/hello</code><code>:</code><code>/bin/bash</code>
<code>47 vuser:x:994:990::</code><code>/var/ftproot</code><code>:</code><code>/bin/bash</code>
<code>48 gentoo:x:1016:1016::</code><code>/root/gentoo</code><code>:</code><code>/bin/bash</code>
<code>49 slackware:x:1017:1017::</code><code>/root/slackware</code><code>:</code><code>/bin/tcsh</code>
-c,count 显示匹配到的行的行数,相当于, COMMAND | wc -l
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -c 'root' /etc/passwd </code>
<code>9</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># grep 'root' /etc/passwd | wc -l</code>
基本正则表达式字符
字符匹配
匹配次数
位置锚定
字符匹配
1) . 匹配任意单个字符, .. 匹配两个字符
2)[] 匹配指定范围内的任意单个字符 (同glob)
3)[^] 匹配范围之外的任意单个字符 (同glob)
使用示例
<code>[root@izpo45bh60h6bsz ~]</code><code># vim a.txt #vim是一个文本编辑命令,进入后按i键,才可编写文本,编写完毕后。按esc键,再按shift 加 : 键,输入wq加Enter键即可。</code>
<code>how are you?</code>
<code>hwo old are you?</code>
<code>HOW ARE YOU?</code>
<code>HWO OLD ARE YOU?</code>
. 匹配任意单个字符
<code># grep 'h.w' a.txt</code>
<code># grep -i 'h.w' a.txt #匹配时,不区分字符大小写</code>
.. 匹配两个字符
<code># grep 'r..t' a.txt</code>
[] 匹配指定范围内的任意单个字符
1)匹配任意单个小写字母
<code># grep 'h[a-z]' a.txt #glob通配时,为所有的字母</code>
<code># grep 'h[[:lower:]]' a.txt</code>
<a href="https://s3.51cto.com/wyfs02/M02/9D/5E/wKiom1l-8OHTGqDxAAAKLBvZFHY753.png" target="_blank"></a>
<a href="https://s2.51cto.com/wyfs02/M00/9D/5D/wKioL1l-8JTQw1VjAAAJVoKEkEA703.png" target="_blank"></a>
2)匹配单个大写字母
<code># grep '[A-Z]W' a.txt</code>
<code># grep '[[:upper:]]W' a.txt</code>
<a href="https://s2.51cto.com/wyfs02/M01/9D/5C/wKiom1l-5qmyk5wVAAAJ6zj1Ygs574.png-wh_500x0-wm_3-wmp_4-s_1041855873.png" target="_blank"></a>
<a href="https://s2.51cto.com/wyfs02/M00/9D/5E/wKioL1l-8WvQPBquAAAKBo7MJwU098.png" target="_blank"></a>
<a href="https://s1.51cto.com/wyfs02/M01/9D/5E/wKioL1l-8aODrdmrAAAKqRtbWQs761.png" target="_blank"></a>
3)匹配aeioU范围内任意单个字符
<code># grep '[aeioU]' a.txt</code>
<code># grep -i '[aeioU]' a.txt</code>
<a href="https://s4.51cto.com/wyfs02/M02/9D/5E/wKioL1l-8gXDvyKhAAAQRMSPHLs103.png" target="_blank"></a>
<a href="https://s5.51cto.com/wyfs02/M02/9D/5E/wKiom1l-8jvzD7TxAAAQN9a122g827.png" target="_blank"></a>
[^] 匹配范围之外的任意单个字符
<code># grep '[^a-z]' a.txt</code>
<code># grep '[^a-zE]' a.txt</code>
<a href="https://s5.51cto.com/wyfs02/M02/9D/5E/wKiom1l-8s3iRhHxAAAPmyotYbk019.png" target="_blank"></a>
<a href="https://s5.51cto.com/wyfs02/M01/9D/5E/wKioL1l-8s3jmq90AAAPrxr9b0g745.png" target="_blank"></a>
匹配任意3个字符后跟t
<code># grep '...t' a.txt</code>
<a href="https://s2.51cto.com/wyfs02/M02/9D/5D/wKioL1l-70aRF-3nAAAHwwDmFjo474.png" target="_blank"></a>
匹配任意3个字母后跟t
<code># grep '[[:alpha:]][[:alpha:]][[:alpha:]]t' a.txt</code>
<code># grep '[a-zA-Z]' a.txt</code>
<a href="https://s2.51cto.com/wyfs02/M01/9D/5D/wKioL1l-762TcgBIAAARS5CJChg193.png" target="_blank"></a>
匹配次数 '前面的单个字符出现的次数'
1)* 匹配前面单个字符出现0、1或多次
2)\? 匹配前面单个字符出现0次或1次
3)\+ 匹配前面的字符'至少1次',>=1次
4) \{m\} 精确匹配前面单个字符m次
5)\{m,n\} 匹配前面单个字符至少m次,至多n次
<code>[root@izpo45bh60h6bsz ~]</code><code># vim output_delimiter.txt</code>
<code>ab</code>
<code>cb</code>
<code>a12b</code>
<code>aab</code>
<code>abb</code>
<code>abababababababab</code>
1)* 匹配前面单个字符出现0、1或多次
<code># grep 'a*b' output_delimiter.txt #你说:“cb能匹配到吗?”</code>
2)\? 匹配前面单个字符出现0次或1次
<code># grep 'a\?b' output_delimiter.txt</code>
<a href="https://s1.51cto.com/wyfs02/M00/9D/60/wKiom1l_CbDQh-DxAAAM3MVbr7M551.png" target="_blank"></a>
3) \+匹配前面单个字符'至少1次'
<code># grep 'a\+b' output_delimiter.txt</code>
<a href="https://s3.51cto.com/wyfs02/M02/9D/60/wKiom1l_C02gnEuMAAAKSmPIFpc605.png" target="_blank"></a>
4)\{m\} 精确匹配前面单个字符m次
<code># grep 'a\{2\}b' output_delimiter.txt</code>
<a href="https://s4.51cto.com/wyfs02/M00/9D/60/wKioL1l_C9_Ad7wLAAAIcjfLe3c565.png" target="_blank"></a>
5)\{m,n\} 匹配前面单个字符至少m次,至多n次;
<code># grep 'a\{1,2\}b' output_delimiter.txt</code>
<a href="https://s1.51cto.com/wyfs02/M01/9D/60/wKioL1l_DDihC70jAAALGKY_uQE146.png" target="_blank"></a>
5.1)m=0时,匹配前面的单个字符至多n次
<code># echo -e 'aaaaaaaaaaaab\naaab\naaab' >> output_delimiter.txt</code>
<code># grep 'a\{0,3\}b' output_delimiter.txt</code>
<a href="https://s5.51cto.com/wyfs02/M01/9D/60/wKiom1l_DxTRuc9sAAAP6aX_0Tk231.png" target="_blank"></a>
5.2)n=时,匹配前面的单个字符至少m次
<code># grep 'a\{1,\}b' output_delimiter.txt</code>
<a href="https://s1.51cto.com/wyfs02/M02/9D/60/wKiom1l_D0qDmteOAAANMtfcLu4109.png" target="_blank"></a>
位置锚定 ‘期望匹配的字符必须出现在某个位置’
1)^ 行首锚定,用于模式最左侧。由正则表达式所匹配到的字串符必须出现在行首
2)$ 行尾锚定,用于模式最右侧。由正则表达式所匹配到的字串符必须出现在行尾
3)^pattern$: 整行只能匹配此模式
4)匹配空白行: ^[[:space:]]*$ 空白可有任意次数
5)\< 或 \b 词首锚定,用于单词模式的左侧
6)\> 或 \b 词尾锚定,用于单词模式的右侧
7) \<PATTERN\> 或 \bPATTERN\b 匹配整个单词,用于单词左右两侧
8)分组
<code># useradd rooter</code>
<code># useradd rootor</code>
1)^ 行首锚定,用于模式最左侧。由正则表达式所匹配到的字串符必须出现在行首
<code># grep '^root' /etc/passwd</code>
<a href="https://s2.51cto.com/wyfs02/M02/9D/60/wKiom1l_EPaAJQX1AAAQlP6bqJI964.png" target="_blank"></a>
2)$ 行尾锚定,用于模式最右侧。由正则表达式所匹配到的字串符必须出现在行尾
<code># grep 'bash$' /etc/passwd</code>
<a href="https://s4.51cto.com/wyfs02/M02/9D/60/wKiom1l_EfPibgWyAABNmsYH5aE243.png" target="_blank"></a>
3)^pattern$: 整行只能匹配此模式
<code># vim c.txt</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># cat -n c.txt</code>
<code> </code><code>1</code>
<code> </code><code>2</code>
<code> </code><code>3</code>
<code> </code><code>4 </code>
<code> </code><code>5</code>
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -n '^$' c.txt </code>
<code>1:</code>
<code>2:</code>
<code>3:</code>
4)匹配空白行: ^[[:space:]]*$ 空白可有任意次数
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -n '^[[:space:]]*' c.txt</code>
<code>4: </code>
<code>5: </code>
<code>[root@izpo45bh60h6bsz ~]</code><code># grep -c '^[[:space:]]*' c.txt</code>
<code>5</code>
5)\< 或 \b 词首锚定,用于单词模式的左侧
<code># grep '\broot' /etc/passwd</code>
<a href="https://s4.51cto.com/wyfs02/M01/9D/60/wKiom1l_FfKAeUl4AAAk2C_yLb4838.png" target="_blank"></a>
6)\> 或 \b 词尾锚定,用于单词模式的右侧
<code># grep 'root\b' /etc/passwd</code>
<a href="https://s3.51cto.com/wyfs02/M02/9D/60/wKioL1l_GVaDwC6fAAAooemrjOE694.png" target="_blank"></a>
7) \<PATTERN\> 或 \bPATTERN\b 匹配整个单词,用于单词左右两侧
<code># grep '\broot\b' /etc/passwd</code>
<a href="https://s1.51cto.com/wyfs02/M02/9D/61/wKiom1l_GxmxhrNEAAAeP4R5u0o093.png" target="_blank"></a>
8)分组: \(\) 将任意个字符当前同一个组件
<code># cat grep.txt </code>
<code>abxy</code>
<code>xxxxxxy</code>
<code>xyxyxyxyabcxy</code>
<code># grep '\(xy\)\+' grep.txt</code>
<a href="https://s1.51cto.com/wyfs02/M01/9D/61/wKioL1l_HU3BL3DNAAAJvgkac4g955.png" target="_blank"></a>
9)后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3
\1:从PATTERN左侧起,第一个左括号与与之对应的右括号之间的模式匹配到的字符
\(ab+\(xy\)*\)
\1: ab+\(xy\)* 模式所匹配到的内容
\2: xy 模式所匹配到的内容
<code># grep '^\([[:alnum:]]\+\>\).*\1$' /etc/passwd</code>
本文转自 lccnx 51CTO博客,原文链接:http://blog.51cto.com/sonlich/1952467,如需转载请自行联系原作者