一、文本处理工具-grep
Linux有被称为文本处理三剑客的工具 grep、sed、awk,本文来讲grep
1.简单的介绍
grep 文本过滤工具,全称为 Global search REgrlat expression and Print out the line。可以在大段的文本之间按指定的过滤条件或模式匹配内容,后进行输出。模式就是用正则表达式编写的过滤条件。
2.命令用法:
标准格式: grep [OPTIONS] PATTERN [FILE...]
option 常用选项 |
选项意义 |
-E |
使用扩展正则表达式 |
-G |
使用基本正则表达式,不过默认就是使用基本正则表达式 |
-F |
使用固定字符串 |
-P |
使用perl语言的正则表达式 |
-i |
忽略字符大小写 |
-o |
仅显示匹配到的字串 |
-q |
静默模式 |
-A # |
显示匹配到的行及后#行 |
-B # |
显示匹配到的行及前#行 |
-C # |
显示匹配到的行及前后#行 |
-v |
取反,意为显示不能够匹配的行 |
–color=auto |
对匹配到的文本加颜色 |
二、正则表达式:
1.什么是正则表达式
由一些特殊字符及文本字符所编写的模式,其中有些字符不表示字符字面意义,而表示控制或通配的功能。分为基本正则表达式和扩展正则表
2.基本的正则表达式:BRE
字符匹配 |
字符代表的意义 |
. |
匹配任意单个字符 |
[ ] |
匹配指定范围内的任意单个字符 |
[^ ] |
匹配范围外的任意单个字符 |
[:alnum:] |
数字和字母 |
[:alpha:] |
任意大小写字母 |
[:blank:] |
|
[:cntrl:] |
控制符 |
[:digit:] |
任意数字 |
[:graph:] |
图形 |
[:lower:] |
任意小写字母 |
[:print:] |
可打印字符 |
[:punct:] |
标点符号 |
[:space:] |
空格 |
[:upper:] |
任意大写字母 |
[:xdigit:] |
十六进制字符 |
- |任意次
\+ |至少一次,至多无限次
\? |可有可无
\{m\} |精确m次
\{m,n\} |至少m,至多n
\{m,\} |至少m,多不限
位置锚定 |
意义 |
^ |
行首锚定 |
$ |
行尾锚定 |
\<或\b |
词首锚定 |
\>或\b |
词尾锚定 |
分组 |
意义 |
\( \) |
将任意个字符当做一个整体做处理 |
分组的意义在于可使用后向引用,使用\1、\2引用第一组或第二组。\1引用第一组,第一组的范围是从左边开始 |
|
第一个括号及与它对应的括号内的内容。 |
|
3.扩展的正则表达式:ERE
字符匹配 |
意义(与基本正则表达式一致) |
. |
匹配任意单个字符 |
[ ] |
匹配指定范围内的任意单个字符 |
[^ ] |
匹配范围外的任意单个字符 |
[:alnum:] |
数字和字母 |
[:alpha:] |
任意大小写字母 |
[:blank:] |
|
[:cntrl:] |
控制符 |
[:digit:] |
任意数字 |
[:graph:] |
图形 |
[:lower:] |
任意小写字母 |
[:print:] |
可打印字符 |
[:punct:] |
标点符号 |
[:space:] |
空格 |
[:upper:] |
任意大写字母 |
[:xdigit:] |
十六进制字符 |
次数匹配 |
意义相较基本正则表达式,省略了\。 |
* |
任意次 |
+ |
至少一次,至多无限次 |
? |
可有可无 |
{m} |
精确m次 |
{m,n} |
至少m,至多n |
{m,} |
至少m,多不限 |
位置锚定 |
意义(与基本正则表达式一致) |
^ |
行首锚定 |
$ |
行尾锚定 |
\<或\b |
词首锚定 |
\>或\b |
词尾锚定 |
分组 |
意义(不需要使用反斜线) |
( ) |
将任意个字符当做一个整体做处理; |
| |
:或者,基本正则表达式中需要转义及小括号; |
三、 练习:
- 显示/proc/meminfo文件中以大小写s开头的行,两种方式;
[root@node1 ~]# grep -i ^s /proc/meminfo [root@node1 ~]# grep ^[Ss] /proc/meminfo [root@node1 ~]# grep -v '^[^Ss]' /proc/meminfo
|
- 显示/etc/passwd文件中,不以/bin/bash结尾的行;
[root@node1 ~]# grep -v '\(/bin/bash\)$' /etc/passwd
|
- 显示/etc/passwd文件中id最大用户的用户名;
[root@node1 ~]# sort -t: -nk3 /etc/passwd | cut -d: -f1 | tail -1
|
- 如果用户root存在,显示器默认的shell程序
[root@node1 ~]# id root &> /dev/null && grep '^root\>' /etc/passwd | cut -d: -f7 || echo 'no such user'
|
- 找出/etc/passwd文件中的两位或三位数
[root@node1 ~]# grep '\<[0-9]\{2,3\}\>' /etc/passwd [root@node1 ~]# grep '\<[[:digit:]]\{2,3\}\>' /etc/passwd [root@node1 ~]# egrep '\<[0-9]{2,3}\>' /etc/passwd [root@node1 ~]# egrep '\<[[:digit:]]{2,3}\>' /etc/passwd
|
- 显示/etc/rc.d/rc.sysinit文件中,至少以一个空白字符开头且后面存在非空白字符的行;
[root@node1 ~]# grep '^[[:space:]]\+[^[:space:]]\+' /etc/rc.d/rc.sysinit [root@node1 ~]# egrep '^[[:space:]]+[^[:space:]]+' /etc/rc.d/rc.sysinit
|
- 找出netstat -tan命令结果中以listen后跟0或1或多个空白字符结尾的行;
[root@node1 ~]# netstat -tan | grep 'LISTEN[[:space:]]*$' [root@node1 ~]# netstat -tan | egrep 'LISTEN[[:space:]]*$'
|
- 添加用户bash,testbash,basher以及nologin,要求其shell为/sbin/nologin/而后找出/etc/passwd文件中用户名用shell名的用户;
[root@node1 ~]# usermod -s /bin/nologin nologin [root@node1 ~]# grep '^\([[:alnum:]]\+\>\).*\1$' /etc/passwd [root@node1 ~]# egrep '^([[:alnum:]]+\>).*\1$' /etc/passwd
|
- 显示当前系统上root、centos或user1用户的默认shell和uid
[root@node1 ~]# grep '^\(root\|centos\|user1\)\>' /etc/passwd | cut -d: -f3,7 [root@node1 ~]# egrep '^(root|centos|user1)\>' /etc/passwd | cut -d: -f3,7
|
- 找出/etc/rc.d/init.d/functions/文件中,某单词后面跟一个小括号的行
[root@node1 ~]# grep '[[:alpha:]]\+\>()' /etc/rc.d/init.d/functions [root@node1 ~]# egrep '[[:alpha:]]+\>\(\)' /etc/rc.d/init.d/functions
|
- 使用echo输出一个路径,使用egrep取出基名
[root@node1 ~]# echo '/etc/sysconfig/network' | grep '[[:alnum:]]\+/\?$' [root@node1 ~]# echo '/etc/sysconfig/network/' | egrep '[[:alnum:]]+/?$'
|
- 使用echo输出一个路径,使用egrep取出目录名
1.[root@node1 ~]# echo "/etc/rc.d/init.d/functions/" | grep -Eo ".*[^/]" | grep -Eo ".*/" 2.[root@node1 ~]# echo "/etc/rc.d/init.d/functions/" | grep -Eo ".*\<" 第12题做了好久都没有做出来,于是在网上找到了解决方案,简单说一下第一个语句的思路: 1的思路:取路径名最难受的就是结尾处的斜线不知道如何处理,1号语句就比较巧妙的用了两个grep语句,---\ 首先第一句grep基于贪婪模式.*把全路径匹配到,但是[^/]又把斜线去掉了,这样就能保证不管给的路径---\ 如何,结果的结尾肯定没有斜线,接着进入第二次grep,再次基于贪婪模式,使用.*匹配一直到斜线的全部内容,斜线后的不做匹配。 2的思路:没有参透,我只能看明白任意字符都行+词首锚定。
|
- 找出ifconfig命令结果中,1-255之间的数值;
[root@node1 ~]# ifconfig | egrep '\<(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\>'
|
- 找出ifconfig命令结果中的ip地址;
[root@node1 ~]# ifconfig | egrep -o '((25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])'
|