一、文本处理工具-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 词尾锚定
分组 意义(不需要使用反斜线)
( ) 将任意个字符当做一个整体做处理;
| :或者,基本正则表达式中需要转义及小括号;

三、 练习:

  1. 显示/proc/meminfo文件中以大小写s开头的行,两种方式;
[root@node1 ~]# grep -i ^s /proc/meminfo
[root@node1 ~]# grep ^[Ss] /proc/meminfo
[root@node1 ~]# grep -v '^[^Ss]' /proc/meminfo
  1. 显示/etc/passwd文件中,不以/bin/bash结尾的行;
[root@node1 ~]# grep -v '\(/bin/bash\)$' /etc/passwd
  1. 显示/etc/passwd文件中id最大用户的用户名;
[root@node1 ~]# sort -t: -nk3 /etc/passwd | cut -d: -f1 | tail -1
  1. 如果用户root存在,显示器默认的shell程序
[root@node1 ~]# id root &> /dev/null && grep '^root\>' /etc/passwd | cut -d: -f7 || echo 'no such user'
  1. 找出/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
  1. 显示/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
  1. 找出netstat -tan命令结果中以listen后跟0或1或多个空白字符结尾的行;
[root@node1 ~]# netstat -tan | grep 'LISTEN[[:space:]]*$'
[root@node1 ~]# netstat -tan | egrep 'LISTEN[[:space:]]*$'
  1. 添加用户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
  1. 显示当前系统上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
  1. 找出/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
  1. 使用echo输出一个路径,使用egrep取出基名
[root@node1 ~]# echo '/etc/sysconfig/network' | grep '[[:alnum:]]\+/\?$'
[root@node1 ~]# echo '/etc/sysconfig/network/' | egrep '[[:alnum:]]+/?$'
  1. 使用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的思路:没有参透,我只能看明白任意字符都行+词首锚定。
  1. 找出ifconfig命令结果中,1-255之间的数值;
[root@node1 ~]# ifconfig | egrep '\<(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\>'
  1. 找出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])'