Linux文本处理工具:
文本搜索
globbing:
*:p*d
/etc/passwd: root
grep, egrep, fgrep
Global search REgular expression and Print out the line.
文本搜索工具,根据用户指定的文本模式(搜索条件)对目标文件进行逐行搜索,显示能匹配到的行。
语法格式:
grep [option]... 'PATTERN' FILE...
--color=auto
正则表达式:
是一类字符所书写的模式,其中许多字符不表示其字面意义,而是表达控制或通配等功能;
元字符:不表示其字面意义,而用于额外功能性描述
正则表达式:正则表达式引擎
基本正则表达式:grep
扩展正则表达式: egrep, grep -E
fgrep: fast, 不支持使用正则表达式
基本正则表达式的元字符:
字符匹配:
.: 匹配任意单个字符
[]: 匹配指定范围内的任意单个字符
[0-9], [[:digit:]]
[a-z], [[:lower:]]
[A-Z], [[:upper:]]
[[:space:]]
[[:punct:]]
[[:alpha:]]
[[:alnum:]]
[^]:
次数匹配元字符:用于实现指定其前面的字符所能够出现的次数
*: 任意长度,它前面的字符可以出现任意次
例如:x*y
xxy, xyy, y,
\?: 0次或1次,它前面的字符是可有可无的
例如:x\?y
xy, y, ay
\{m\}: m次,它前的字符要出现m次
例如:x\{2\}y
xy, xxy, y, xxxxy, xyy
\{m,n\}: 至少m次,至多n次
例如:x\{2,5\}y
xy, y, xxy
\{m,\}:至少m次
\{0,n\}: 至多n次
.*:任意长度的任意字符
工作于贪婪模式:尽可能多的去匹配
位置锚定:
^: 行首锚定;
写在模式最左侧
$: 行尾锚定:
写在模式最右侧
^$: 空白行
不包含特殊字符的连续字符组成的串叫单词:
\<: 词首,出现于单词左侧,\b
\<char
\>: 词尾,出现于单词右侧, \b
char\>
分组:
\(\)
例如:\(ab\)*
分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被引用
引用:
例如\(ab\(x\)y\).*\(mn\)
有编号:自左而后的左括号,以及与其匹配右括号
\(a\(b\(c\)\)mn\(x\)\).*\1
\#: 引用第n个括号所匹配到的内容,而非模式本身
例如:
\(ab\?c\).*\1
abcmnaaa
abcmnabc
abcmnac
acxyac
命令选项:
-v: 反向选取
-o: 仅显示匹配的字串,而非字串所在的行
-i: ignore-case,忽略字符大小写
-E: 支持使用扩展正则表达式
-A #
-B #
-C #
练习:
1、显示/proc/meminfo文件中以大写或小写S开头的行;
# grep -i '^s' /proc/meminfo
# grep '^[Ss]' /proc/meminfo
# grep -E '^(S|s)' /proc/meminfo
2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
# grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1
3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;
进一步:仅显示上述结果中其ID号最大的用户;
# grep "/bin/bash$" /etc/passwd | sort -t: -k3 -n | tail -1 | cut -d: -f1
4、找出/etc/passwd文件中的一位数或两位数;
# grep "\<[0-9][0-9]\?\>" /etc/passwd
# grep "\<[0-9]\{1,2\}\>" /etc/passwd
5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
# grep "^[[:space:]]\{1,\}" /boot/grub/grub.conf
6、显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
# grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
7、找出netstat -tan命令执行结果中以'LISTEN'结尾的行;
# netstat -tan | grep "LISTEN[[:space:]]*$"
8、添加用户bash, testbash, basher, nologin(SHELL为/sbin/nologin),而找出当前系统上其用户名和默认shell相同的用户;
# grep "^\([[:alnum:]]\{1,\}\):.*\1$" /etc/passwd
9、扩展题:新建一个文本文件,假设有如下内容:
He like his lover.
He love his lover.
He like his liker.
He love his liker.
找出其中最后一个单词是由此前某单词加r构成的行。
\(l..e\).*\1r
扩展正则表达式:
字符匹配:
.
[]
[^]
次数匹配:
*:任意次
?: 0次或1次
+: 至少1次;
{m}: 精确匹配m次
{m,n}: 至少m次,至多n次
{m,}
{0,n}
锚定:
^
$
\<, \b
\>, \b
^$, ^[[:space:]]*$
分组:
()
引用:\1, \2, \3
或者:
a|b: a或者b
con(C|c)at
concat或conCat?
conC或cat
grep -E 'PATTERN' FILE...
egrep 'PATTERN' FILE...
练习:使用扩展的正则表达式
10、显示当前系统上root、fedora或user1用户的默认shell;
# grep -E "^(root|fedora|user1):" /etc/passwd | cut -d: -f7
11、找出/etc/rc.d/init.d/functions文件中某单词后跟一组小括号“()”行;
# grep -o -E "\<[[:alnum:]]+\>\(\)" /etc/rc.d/init.d/functions
12、使用echo命令输出一个路径,而后使用grep取出其基名;
echo "/etc/sysconfig/" | grep -o -E "[[:alnum:]]+/?"
# echo "/etc/sysconfig/" | grep -o -E "[^/]+/?$" | cut -d/ -f1
13、找出ifconfig命令结果中的1-255之间的数字;
# ifconfig | grep -o -E "\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>"
14、挑战题:写一个模式,能匹配合理的ipv4地址;
1.0.0.1-239.255.255.255