Linux 上文本处理三剑客
-
grep
:文本过滤(模式:pattern
)工具
grep
(基本匹配),egrep
(扩展匹配),fgrep
(快速匹配 - 把要匹配的内容当做固定字符串而不是一个 pattern
)
-
sed
:stream editor,文本编辑工具
-
awk
:Linux 上的实现是 gawk
(它是另外一种编程语言),文本报告生成器(格式更美观)
grep: Global search regular expression and Print out the line
作用:文本搜索工具,根据用户指定的“模式”对目标文本朱行进行匹配检查并打印匹配到的行
模式:由正则表达式字符及文本字符搜编写的过滤条件
REGEXP:由一类特殊字符及文本字符搜编写的模式,其中有些字符不表示字符字面含义(元字符),而表示控制或通配的功能
分两类:
基本正则表达式:BRE
扩展正则表达式:ERE
grep -E,egrep
正则表达式引擎:用于正则表达式解析与匹配检查(注意:不同的命令或工具的表达式引擎不同,所支持的正则表达式语法可能也不相同)
例子:比如搜索 /etc/passwd 下的 root
使用命令:
grep root /etc/passwd 注意这种方式会用正则引擎解析(速度慢)
fgrep root /etc/passwd 使用 fast grep 这种方式,会把 root 当做字符串(而不是元字符)直接搜索,速度快
语法:grep [OPTIONS] PATTERN [FILE...]
选项:
--color=auto:对匹配到的文本着色显示
-v, --invert-match:显示不能被 pattern 匹配到的行
-i, --ignore-case:忽略字符大小写
-o, --only-matching:仅显示匹配到字符串,不显示匹配到的字符串之外的其它内容
-q, --quiet, --silent:静默模式,不输出任何信息(主要用于编写脚本中,通过 $? 查看是否匹配到了结果)
Context Line Control:上下文控制
-A NUM, --after-context=NUM:后NUM行
-B NUM, --before-context=NUM:前NUM行
-C NUM, -NUM, --context=NUM:前后各NUM行
-E:使用 ERE
基本正则表达式元字符:
1. 字符匹配:
.: 匹配任意单个字符
[]: 匹配指定范围内的任意单个字符
[^]: 匹配指定范围外的任意单个字符
[:digit:]、[:lower:]、[:upper:]、[:alpha:]、[:alnum:]、[:punct:]、[:space:]
2. 匹配次数:用在要指定次数的字符后面,用户指定前面的自如要出现的次数
*:匹配前面的字符任意次
例如:grep "x*y"
abxy
xay
xxxxxy
贪婪模式:(默认情况下,正则表达式工作于贪婪模式 - 能匹配多少就匹配多少)
.*:任意长度的任意字符
\?:匹配其前面的字符0或1次,即前面的可有可无
\+:匹配其前面的字符至少1次
\{m\}:匹配前面的字符 m 次
\{m,n\}:匹配前面的字符至少 m 次,至多 n 次
\{0,n\}:匹配前面的字符至多 n 次
\{m,\}:匹配钱的字符最少 m 次
3. 位置锚定
^:行首锚定,用于模式的最左侧
$:行尾锚定,用于模式的最右侧
^PATTERN$:用于模式匹配整行
^$: 空行
^[[:space:]]*$
\< 或 \b: 词首锚定,用于单词模式的左侧,border 边界的意思
\> 或 \b: 词尾锚定,用于单词模式的右侧
\<PATTERN\>: 匹配整个单词
4. 分组:
\(\): 将一个或多个字符捆绑在一起,当做一个整体进行处理
\(xy\)*ab
注意:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命令方式为:\1, \2, \3, ...
\1: 从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
\(ab\+\(xy\)*\)
\1: ab\+\(xy\)*
\2: xy
后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身。
练习1
- 显示
/proc/meminfo
文件中以大小写s开头的行:(要求:使用两种方式,-i, ^, \b
)
1. grep -i "^s" /proc/meminfo
2. grep -i "\<s" /proc/meminfo
3. grep -i "\bs" /proc/meminfo
4. grep ^[sS] /proc/meminfo
5. grep \<[sS] /proc/meminfo
6. grep "\b[sS]" /proc/meminfo
- 显示
/etc/passwd
文件中 ID 号最大的用户的用户名
sort -t: -k3 -nr /etc/passwd | top -1 | cut -d: -f1
- 显示
/etc/passwd
文件中不以 /bin/bash
结尾的行
grep -v "/bin/bash$" /etc/passwd
- 如果用户 root 存在,显示其默认的 shell 程序
id root &> /dev/null && grep "^root\>" /etc/passwd | cut -d: -f7 || echo "user not exist"
- 找出
/etc/passwd
中的两位或三位数
grep "\<[[:digit:]]\{2,3\}\>" /etc/passwd
grep "\<[0-9]\{2,3\}\>" /etc/passwd
注意必须加上词首,词尾绑定,否则可能把四位数的也匹配出来
- 显示
/etc/grub2.cfg
文件中,至少以一个空白字符开头的且后面存在非空白字符的行
grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
- 找出
netstat -tan
,centos7中使用 ss -tan
命令的结果中以 ‘LISTEN’ 后跟0、1或多个空白字符结尾的行
netstat -tan | grep "LISTEN[[:space:]]*$"
注意 ss 中 LISTEN 出现在第一列
ss -tan | grep "LISTEN[[:space:]]*"
- 添加用户bash、testbash、basher以及nologin(其 shell 为
/sbin/noglogin
),而后找出 /etc/passwd
文件中用户名同 shell 名相同的行 --- 主要考察后向引用
useradd bash
useradd basher
useradd testbash
useradd -s /sbin/nologin nologin
grep "^\([[:alnum:]]\+\>\).*\1$" /etc/passwd
命令解释:
^: 首用户名开始
[[:alnum:]]: 所有字母和数字
\>: 锚定边界为用户名
\+: 字母和数字可以出现一次或多次
.*: 后面可以出现任意字符
\1: 划定【后向引用】为用户名,即:[[:alnum:]]\+\>\).*
$: 锚定最后为 shell
练习2
- 编写一个脚本,实现如下功能
如果用户user1存在,就显示其存在,否则添加之
显示添加的用户的id号等信息
#!/bin/bash
id user &> /dev/null && echo "user exists" || useradd user1
id user1
- 编写一个脚本,实现如下功能
如果 root 用户登录了当前系统,就显示 root 用户在线,否则说明其未登录
#!/bin/bash
w | grep "root\>" &> /dev/null && echo "user logined" || echo "user not login"
网友评论