一、文本处理工具-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])'